{"data":{"images":{"edges":[{"node":{"name":"0-11-15-misfit-per-receiver-table-view","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/a9af263ff4e7d45703bfce1de94269c6/d3e0c/0-11-15-misfit-per-receiver-table-view.png","srcSet":"/static/a9af263ff4e7d45703bfce1de94269c6/cd787/0-11-15-misfit-per-receiver-table-view.png 112w,\n/static/a9af263ff4e7d45703bfce1de94269c6/8075f/0-11-15-misfit-per-receiver-table-view.png 224w,\n/static/a9af263ff4e7d45703bfce1de94269c6/d3e0c/0-11-15-misfit-per-receiver-table-view.png 448w","sizes":"(min-width: 448px) 448px, 100vw"},"sources":[{"srcSet":"/static/a9af263ff4e7d45703bfce1de94269c6/bff52/0-11-15-misfit-per-receiver-table-view.webp 112w,\n/static/a9af263ff4e7d45703bfce1de94269c6/1cb23/0-11-15-misfit-per-receiver-table-view.webp 224w,\n/static/a9af263ff4e7d45703bfce1de94269c6/504eb/0-11-15-misfit-per-receiver-table-view.webp 448w","type":"image/webp","sizes":"(min-width: 448px) 448px, 100vw"}]},"width":448,"height":462}}}},{"node":{"name":"0-11-16-misfit-histograms","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/0c4b51f06b9022f5a4af9b01b30e597d/bbcbe/0-11-16-misfit-histograms.png","srcSet":"/static/0c4b51f06b9022f5a4af9b01b30e597d/95973/0-11-16-misfit-histograms.png 224w,\n/static/0c4b51f06b9022f5a4af9b01b30e597d/c7d05/0-11-16-misfit-histograms.png 449w,\n/static/0c4b51f06b9022f5a4af9b01b30e597d/bbcbe/0-11-16-misfit-histograms.png 897w","sizes":"(min-width: 897px) 897px, 100vw"},"sources":[{"srcSet":"/static/0c4b51f06b9022f5a4af9b01b30e597d/c9c1d/0-11-16-misfit-histograms.webp 224w,\n/static/0c4b51f06b9022f5a4af9b01b30e597d/e7c4a/0-11-16-misfit-histograms.webp 449w,\n/static/0c4b51f06b9022f5a4af9b01b30e597d/b515d/0-11-16-misfit-histograms.webp 897w","type":"image/webp","sizes":"(min-width: 897px) 897px, 100vw"}]},"width":897,"height":503}}}},{"node":{"name":"0-11-41-3d-box-domain-visualization","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/6243346caf8b09d4aa61f71f67a32455/a3597/0-11-41-3d-box-domain-visualization.png","srcSet":"/static/6243346caf8b09d4aa61f71f67a32455/81c62/0-11-41-3d-box-domain-visualization.png 250w,\n/static/6243346caf8b09d4aa61f71f67a32455/818f8/0-11-41-3d-box-domain-visualization.png 500w,\n/static/6243346caf8b09d4aa61f71f67a32455/a3597/0-11-41-3d-box-domain-visualization.png 1000w","sizes":"(min-width: 1000px) 1000px, 100vw"},"sources":[{"srcSet":"/static/6243346caf8b09d4aa61f71f67a32455/e1875/0-11-41-3d-box-domain-visualization.webp 250w,\n/static/6243346caf8b09d4aa61f71f67a32455/49bbe/0-11-41-3d-box-domain-visualization.webp 500w,\n/static/6243346caf8b09d4aa61f71f67a32455/bec62/0-11-41-3d-box-domain-visualization.webp 1000w","type":"image/webp","sizes":"(min-width: 1000px) 1000px, 100vw"}]},"width":1000,"height":316}}}},{"node":{"name":"0-11-41-geophone-responses","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/501cd7bea63071200e39f736868d5531/449fa/0-11-41-geophone-responses.png","srcSet":"/static/501cd7bea63071200e39f736868d5531/abf79/0-11-41-geophone-responses.png 214w,\n/static/501cd7bea63071200e39f736868d5531/3d24f/0-11-41-geophone-responses.png 428w,\n/static/501cd7bea63071200e39f736868d5531/449fa/0-11-41-geophone-responses.png 856w","sizes":"(min-width: 856px) 856px, 100vw"},"sources":[{"srcSet":"/static/501cd7bea63071200e39f736868d5531/c8aaf/0-11-41-geophone-responses.webp 214w,\n/static/501cd7bea63071200e39f736868d5531/be877/0-11-41-geophone-responses.webp 428w,\n/static/501cd7bea63071200e39f736868d5531/e1c71/0-11-41-geophone-responses.webp 856w","type":"image/webp","sizes":"(min-width: 856px) 856px, 100vw"}]},"width":856,"height":712}}}},{"node":{"name":"0-11-16-box-domain-viz","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#c8c8c8","images":{"fallback":{"src":"/static/02598e2d16b92c58ce165c8cb6eb26d1/019c3/0-11-16-box-domain-viz.png","srcSet":"/static/02598e2d16b92c58ce165c8cb6eb26d1/aff56/0-11-16-box-domain-viz.png 141w,\n/static/02598e2d16b92c58ce165c8cb6eb26d1/f633d/0-11-16-box-domain-viz.png 283w,\n/static/02598e2d16b92c58ce165c8cb6eb26d1/019c3/0-11-16-box-domain-viz.png 565w","sizes":"(min-width: 565px) 565px, 100vw"},"sources":[{"srcSet":"/static/02598e2d16b92c58ce165c8cb6eb26d1/b34fc/0-11-16-box-domain-viz.webp 141w,\n/static/02598e2d16b92c58ce165c8cb6eb26d1/c0fc3/0-11-16-box-domain-viz.webp 283w,\n/static/02598e2d16b92c58ce165c8cb6eb26d1/866af/0-11-16-box-domain-viz.webp 565w","type":"image/webp","sizes":"(min-width: 565px) 565px, 100vw"}]},"width":565,"height":556}}}},{"node":{"name":"0-11-16-interval-window-tables","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/548bfa292789454779cd43cb0c102f48/3405e/0-11-16-interval-window-tables.png","srcSet":"/static/548bfa292789454779cd43cb0c102f48/917a5/0-11-16-interval-window-tables.png 224w,\n/static/548bfa292789454779cd43cb0c102f48/06689/0-11-16-interval-window-tables.png 448w,\n/static/548bfa292789454779cd43cb0c102f48/3405e/0-11-16-interval-window-tables.png 896w","sizes":"(min-width: 896px) 896px, 100vw"},"sources":[{"srcSet":"/static/548bfa292789454779cd43cb0c102f48/ef4a8/0-11-16-interval-window-tables.webp 224w,\n/static/548bfa292789454779cd43cb0c102f48/56e25/0-11-16-interval-window-tables.webp 448w,\n/static/548bfa292789454779cd43cb0c102f48/42337/0-11-16-interval-window-tables.webp 896w","type":"image/webp","sizes":"(min-width: 896px) 896px, 100vw"}]},"width":896,"height":464}}}},{"node":{"name":"0-11-26-trust-region-visualization","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/48235d613472466088e1503e1bf61bd1/19fbf/0-11-26-trust-region-visualization.png","srcSet":"/static/48235d613472466088e1503e1bf61bd1/7c4f1/0-11-26-trust-region-visualization.png 239w,\n/static/48235d613472466088e1503e1bf61bd1/aed91/0-11-26-trust-region-visualization.png 478w,\n/static/48235d613472466088e1503e1bf61bd1/19fbf/0-11-26-trust-region-visualization.png 956w","sizes":"(min-width: 956px) 956px, 100vw"},"sources":[{"srcSet":"/static/48235d613472466088e1503e1bf61bd1/ba8a6/0-11-26-trust-region-visualization.webp 239w,\n/static/48235d613472466088e1503e1bf61bd1/0fef1/0-11-26-trust-region-visualization.webp 478w,\n/static/48235d613472466088e1503e1bf61bd1/28755/0-11-26-trust-region-visualization.webp 956w","type":"image/webp","sizes":"(min-width: 956px) 956px, 100vw"}]},"width":956,"height":391}}}},{"node":{"name":"0-11-41-graph-space-optimal-transport","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#585868","images":{"fallback":{"src":"/static/b30fae11dd7c3ab1497c0a43bbbf5aae/aadda/0-11-41-graph-space-optimal-transport.png","srcSet":"/static/b30fae11dd7c3ab1497c0a43bbbf5aae/360c9/0-11-41-graph-space-optimal-transport.png 603w,\n/static/b30fae11dd7c3ab1497c0a43bbbf5aae/d44b4/0-11-41-graph-space-optimal-transport.png 1205w,\n/static/b30fae11dd7c3ab1497c0a43bbbf5aae/aadda/0-11-41-graph-space-optimal-transport.png 2410w","sizes":"(min-width: 2410px) 2410px, 100vw"},"sources":[{"srcSet":"/static/b30fae11dd7c3ab1497c0a43bbbf5aae/45c7f/0-11-41-graph-space-optimal-transport.webp 603w,\n/static/b30fae11dd7c3ab1497c0a43bbbf5aae/6b63e/0-11-41-graph-space-optimal-transport.webp 1205w,\n/static/b30fae11dd7c3ab1497c0a43bbbf5aae/3ba80/0-11-41-graph-space-optimal-transport.webp 2410w","type":"image/webp","sizes":"(min-width: 2410px) 2410px, 100vw"}]},"width":2410,"height":1023}}}},{"node":{"name":"0-11-44-fix-shotgather-for-single-data-names","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/e091295f9d13eacc9605cffa7d1d0818/5608e/0-11-44-fix-shotgather-for-single-data-names.png","srcSet":"/static/e091295f9d13eacc9605cffa7d1d0818/3aa92/0-11-44-fix-shotgather-for-single-data-names.png 242w,\n/static/e091295f9d13eacc9605cffa7d1d0818/4ecc6/0-11-44-fix-shotgather-for-single-data-names.png 484w,\n/static/e091295f9d13eacc9605cffa7d1d0818/5608e/0-11-44-fix-shotgather-for-single-data-names.png 967w","sizes":"(min-width: 967px) 967px, 100vw"},"sources":[{"srcSet":"/static/e091295f9d13eacc9605cffa7d1d0818/7aa5d/0-11-44-fix-shotgather-for-single-data-names.webp 242w,\n/static/e091295f9d13eacc9605cffa7d1d0818/c9eff/0-11-44-fix-shotgather-for-single-data-names.webp 484w,\n/static/e091295f9d13eacc9605cffa7d1d0818/21557/0-11-44-fix-shotgather-for-single-data-names.webp 967w","type":"image/webp","sizes":"(min-width: 967px) 967px, 100vw"}]},"width":967,"height":576}}}},{"node":{"name":"0-12-01-performance-tracking-opt","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/842eb5abee7f9c8c8ddd723897cad2cf/e637f/0-12-01-performance-tracking-opt.png","srcSet":"/static/842eb5abee7f9c8c8ddd723897cad2cf/611b9/0-12-01-performance-tracking-opt.png 148w,\n/static/842eb5abee7f9c8c8ddd723897cad2cf/5d61a/0-12-01-performance-tracking-opt.png 297w,\n/static/842eb5abee7f9c8c8ddd723897cad2cf/e637f/0-12-01-performance-tracking-opt.png 593w","sizes":"(min-width: 593px) 593px, 100vw"},"sources":[{"srcSet":"/static/842eb5abee7f9c8c8ddd723897cad2cf/aec57/0-12-01-performance-tracking-opt.webp 148w,\n/static/842eb5abee7f9c8c8ddd723897cad2cf/40c56/0-12-01-performance-tracking-opt.webp 297w,\n/static/842eb5abee7f9c8c8ddd723897cad2cf/78027/0-12-01-performance-tracking-opt.webp 593w","type":"image/webp","sizes":"(min-width: 593px) 593px, 100vw"}]},"width":593,"height":665}}}},{"node":{"name":"0-11-15-misfit-per-receiver-map","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#e8e8e8","images":{"fallback":{"src":"/static/df19f68fc26627ff0845c1491174d787/a3860/0-11-15-misfit-per-receiver-map.png","srcSet":"/static/df19f68fc26627ff0845c1491174d787/16dcc/0-11-15-misfit-per-receiver-map.png 246w,\n/static/df19f68fc26627ff0845c1491174d787/02815/0-11-15-misfit-per-receiver-map.png 491w,\n/static/df19f68fc26627ff0845c1491174d787/a3860/0-11-15-misfit-per-receiver-map.png 982w","sizes":"(min-width: 982px) 982px, 100vw"},"sources":[{"srcSet":"/static/df19f68fc26627ff0845c1491174d787/47605/0-11-15-misfit-per-receiver-map.webp 246w,\n/static/df19f68fc26627ff0845c1491174d787/860a1/0-11-15-misfit-per-receiver-map.webp 491w,\n/static/df19f68fc26627ff0845c1491174d787/d6f7f/0-11-15-misfit-per-receiver-map.webp 982w","type":"image/webp","sizes":"(min-width: 982px) 982px, 100vw"}]},"width":982,"height":399}}}},{"node":{"name":"0-11-15-side-set-grid-point-3d","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/453d6724b1df2cb765b469336e10d128/86bb8/0-11-15-side-set-grid-point-3d.png","srcSet":"/static/453d6724b1df2cb765b469336e10d128/7835b/0-11-15-side-set-grid-point-3d.png 147w,\n/static/453d6724b1df2cb765b469336e10d128/ef0d7/0-11-15-side-set-grid-point-3d.png 294w,\n/static/453d6724b1df2cb765b469336e10d128/86bb8/0-11-15-side-set-grid-point-3d.png 587w","sizes":"(min-width: 587px) 587px, 100vw"},"sources":[{"srcSet":"/static/453d6724b1df2cb765b469336e10d128/6514e/0-11-15-side-set-grid-point-3d.webp 147w,\n/static/453d6724b1df2cb765b469336e10d128/f4b32/0-11-15-side-set-grid-point-3d.webp 294w,\n/static/453d6724b1df2cb765b469336e10d128/61ed0/0-11-15-side-set-grid-point-3d.webp 587w","type":"image/webp","sizes":"(min-width: 587px) 587px, 100vw"}]},"width":587,"height":518}}}},{"node":{"name":"0-11-16-receiver-weight-map","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#e8e8e8","images":{"fallback":{"src":"/static/56034b1cd739a8aa61b9a04926dd1615/e8aba/0-11-16-receiver-weight-map.png","srcSet":"/static/56034b1cd739a8aa61b9a04926dd1615/eb070/0-11-16-receiver-weight-map.png 245w,\n/static/56034b1cd739a8aa61b9a04926dd1615/6db02/0-11-16-receiver-weight-map.png 490w,\n/static/56034b1cd739a8aa61b9a04926dd1615/e8aba/0-11-16-receiver-weight-map.png 980w","sizes":"(min-width: 980px) 980px, 100vw"},"sources":[{"srcSet":"/static/56034b1cd739a8aa61b9a04926dd1615/7515f/0-11-16-receiver-weight-map.webp 245w,\n/static/56034b1cd739a8aa61b9a04926dd1615/9dfd1/0-11-16-receiver-weight-map.webp 490w,\n/static/56034b1cd739a8aa61b9a04926dd1615/0ec23/0-11-16-receiver-weight-map.webp 980w","type":"image/webp","sizes":"(min-width: 980px) 980px, 100vw"}]},"width":980,"height":399.99999999999994}}}},{"node":{"name":"0-11-16-uniform-mesh-refinement","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#080808","images":{"fallback":{"src":"/static/991de127172be09aa9a688ec308141b8/a12bd/0-11-16-uniform-mesh-refinement.png","srcSet":"/static/991de127172be09aa9a688ec308141b8/7fe30/0-11-16-uniform-mesh-refinement.png 366w,\n/static/991de127172be09aa9a688ec308141b8/ca111/0-11-16-uniform-mesh-refinement.png 732w,\n/static/991de127172be09aa9a688ec308141b8/a12bd/0-11-16-uniform-mesh-refinement.png 1464w","sizes":"(min-width: 1464px) 1464px, 100vw"},"sources":[{"srcSet":"/static/991de127172be09aa9a688ec308141b8/6e1cc/0-11-16-uniform-mesh-refinement.webp 366w,\n/static/991de127172be09aa9a688ec308141b8/fe337/0-11-16-uniform-mesh-refinement.webp 732w,\n/static/991de127172be09aa9a688ec308141b8/07322/0-11-16-uniform-mesh-refinement.webp 1464w","type":"image/webp","sizes":"(min-width: 1464px) 1464px, 100vw"}]},"width":1464,"height":628}}}},{"node":{"name":"0-11-26-improve-misfit-visualization","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/2741567393fe60ffa44b207d3dc5787d/231cd/0-11-26-improve-misfit-visualization.png","srcSet":"/static/2741567393fe60ffa44b207d3dc5787d/651fb/0-11-26-improve-misfit-visualization.png 500w,\n/static/2741567393fe60ffa44b207d3dc5787d/ce1b9/0-11-26-improve-misfit-visualization.png 999w,\n/static/2741567393fe60ffa44b207d3dc5787d/231cd/0-11-26-improve-misfit-visualization.png 1998w","sizes":"(min-width: 1998px) 1998px, 100vw"},"sources":[{"srcSet":"/static/2741567393fe60ffa44b207d3dc5787d/9f7bc/0-11-26-improve-misfit-visualization.webp 500w,\n/static/2741567393fe60ffa44b207d3dc5787d/b1554/0-11-26-improve-misfit-visualization.webp 999w,\n/static/2741567393fe60ffa44b207d3dc5787d/f4a92/0-11-26-improve-misfit-visualization.webp 1998w","type":"image/webp","sizes":"(min-width: 1998px) 1998px, 100vw"}]},"width":1998,"height":1078}}}},{"node":{"name":"0-11-41-improved-shotgather-visualization","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/2a17df02138ee7794a307b9410ded77d/a4678/0-11-41-improved-shotgather-visualization.png","srcSet":"/static/2a17df02138ee7794a307b9410ded77d/d875c/0-11-41-improved-shotgather-visualization.png 244w,\n/static/2a17df02138ee7794a307b9410ded77d/3b251/0-11-41-improved-shotgather-visualization.png 489w,\n/static/2a17df02138ee7794a307b9410ded77d/a4678/0-11-41-improved-shotgather-visualization.png 977w","sizes":"(min-width: 977px) 977px, 100vw"},"sources":[{"srcSet":"/static/2a17df02138ee7794a307b9410ded77d/2f531/0-11-41-improved-shotgather-visualization.webp 244w,\n/static/2a17df02138ee7794a307b9410ded77d/10416/0-11-41-improved-shotgather-visualization.webp 489w,\n/static/2a17df02138ee7794a307b9410ded77d/1a631/0-11-41-improved-shotgather-visualization.webp 977w","type":"image/webp","sizes":"(min-width: 977px) 977px, 100vw"}]},"width":977,"height":600}}}},{"node":{"name":"0-11-20-local-refinement-cylindrical","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/e3b7951b24cd58337d8a33dbee22cf3b/81de9/0-11-20-local-refinement-cylindrical.png","srcSet":"/static/e3b7951b24cd58337d8a33dbee22cf3b/922b4/0-11-20-local-refinement-cylindrical.png 327w,\n/static/e3b7951b24cd58337d8a33dbee22cf3b/a7822/0-11-20-local-refinement-cylindrical.png 654w,\n/static/e3b7951b24cd58337d8a33dbee22cf3b/81de9/0-11-20-local-refinement-cylindrical.png 1308w","sizes":"(min-width: 1308px) 1308px, 100vw"},"sources":[{"srcSet":"/static/e3b7951b24cd58337d8a33dbee22cf3b/c79c4/0-11-20-local-refinement-cylindrical.webp 327w,\n/static/e3b7951b24cd58337d8a33dbee22cf3b/d3e54/0-11-20-local-refinement-cylindrical.webp 654w,\n/static/e3b7951b24cd58337d8a33dbee22cf3b/899fb/0-11-20-local-refinement-cylindrical.webp 1308w","type":"image/webp","sizes":"(min-width: 1308px) 1308px, 100vw"}]},"width":1308,"height":539}}}},{"node":{"name":"0-11-15-smoothiesem","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/3c90cab393b827095817a854660b86a2/15bd5/0-11-15-smoothiesem.png","srcSet":"/static/3c90cab393b827095817a854660b86a2/9116a/0-11-15-smoothiesem.png 208w,\n/static/3c90cab393b827095817a854660b86a2/f24cb/0-11-15-smoothiesem.png 417w,\n/static/3c90cab393b827095817a854660b86a2/15bd5/0-11-15-smoothiesem.png 833w","sizes":"(min-width: 833px) 833px, 100vw"},"sources":[{"srcSet":"/static/3c90cab393b827095817a854660b86a2/99965/0-11-15-smoothiesem.webp 208w,\n/static/3c90cab393b827095817a854660b86a2/244f3/0-11-15-smoothiesem.webp 417w,\n/static/3c90cab393b827095817a854660b86a2/00390/0-11-15-smoothiesem.webp 833w","type":"image/webp","sizes":"(min-width: 833px) 833px, 100vw"}]},"width":833,"height":561}}}},{"node":{"name":"0-11-41-point-to-line-source-conversion","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/00d9d94dde8857cbe7dec7572dacd3fb/db47a/0-11-41-point-to-line-source-conversion.png","srcSet":"/static/00d9d94dde8857cbe7dec7572dacd3fb/28c20/0-11-41-point-to-line-source-conversion.png 225w,\n/static/00d9d94dde8857cbe7dec7572dacd3fb/f69e0/0-11-41-point-to-line-source-conversion.png 450w,\n/static/00d9d94dde8857cbe7dec7572dacd3fb/db47a/0-11-41-point-to-line-source-conversion.png 900w","sizes":"(min-width: 900px) 900px, 100vw"},"sources":[{"srcSet":"/static/00d9d94dde8857cbe7dec7572dacd3fb/66e9d/0-11-41-point-to-line-source-conversion.webp 225w,\n/static/00d9d94dde8857cbe7dec7572dacd3fb/ae6b5/0-11-41-point-to-line-source-conversion.webp 450w,\n/static/00d9d94dde8857cbe7dec7572dacd3fb/a2b13/0-11-41-point-to-line-source-conversion.webp 900w","type":"image/webp","sizes":"(min-width: 900px) 900px, 100vw"}]},"width":900,"height":407}}}},{"node":{"name":"0-11-15-spherical-chunks-map-viz","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#98d8e8","images":{"fallback":{"src":"/static/01239b67e805ebb45e226733b0a13a1a/429b0/0-11-15-spherical-chunks-map-viz.png","srcSet":"/static/01239b67e805ebb45e226733b0a13a1a/ed13e/0-11-15-spherical-chunks-map-viz.png 195w,\n/static/01239b67e805ebb45e226733b0a13a1a/ed73e/0-11-15-spherical-chunks-map-viz.png 390w,\n/static/01239b67e805ebb45e226733b0a13a1a/429b0/0-11-15-spherical-chunks-map-viz.png 780w","sizes":"(min-width: 780px) 780px, 100vw"},"sources":[{"srcSet":"/static/01239b67e805ebb45e226733b0a13a1a/0266c/0-11-15-spherical-chunks-map-viz.webp 195w,\n/static/01239b67e805ebb45e226733b0a13a1a/0feaa/0-11-15-spherical-chunks-map-viz.webp 390w,\n/static/01239b67e805ebb45e226733b0a13a1a/8009a/0-11-15-spherical-chunks-map-viz.webp 780w","type":"image/webp","sizes":"(min-width: 780px) 780px, 100vw"}]},"width":780,"height":400}}}},{"node":{"name":"0-11-30-spherical-chunk-polygon","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#98d8e8","images":{"fallback":{"src":"/static/a3d89bb2a417a88c82a3a9ca8065ef03/339e9/0-11-30-spherical-chunk-polygon.png","srcSet":"/static/a3d89bb2a417a88c82a3a9ca8065ef03/160bb/0-11-30-spherical-chunk-polygon.png 201w,\n/static/a3d89bb2a417a88c82a3a9ca8065ef03/95979/0-11-30-spherical-chunk-polygon.png 402w,\n/static/a3d89bb2a417a88c82a3a9ca8065ef03/339e9/0-11-30-spherical-chunk-polygon.png 804w","sizes":"(min-width: 804px) 804px, 100vw"},"sources":[{"srcSet":"/static/a3d89bb2a417a88c82a3a9ca8065ef03/a0108/0-11-30-spherical-chunk-polygon.webp 201w,\n/static/a3d89bb2a417a88c82a3a9ca8065ef03/f5897/0-11-30-spherical-chunk-polygon.webp 402w,\n/static/a3d89bb2a417a88c82a3a9ca8065ef03/dae3b/0-11-30-spherical-chunk-polygon.webp 804w","type":"image/webp","sizes":"(min-width: 804px) 804px, 100vw"}]},"width":804,"height":374}}}},{"node":{"name":"0-11-16-smoothiesem-topo-ellipticity-and-ocean-loading","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/00e384e52142e92b2ae60847f493220f/49410/0-11-16-smoothiesem-topo-ellipticity-and-ocean-loading.png","srcSet":"/static/00e384e52142e92b2ae60847f493220f/bc02f/0-11-16-smoothiesem-topo-ellipticity-and-ocean-loading.png 147w,\n/static/00e384e52142e92b2ae60847f493220f/98ce9/0-11-16-smoothiesem-topo-ellipticity-and-ocean-loading.png 295w,\n/static/00e384e52142e92b2ae60847f493220f/49410/0-11-16-smoothiesem-topo-ellipticity-and-ocean-loading.png 589w","sizes":"(min-width: 589px) 589px, 100vw"},"sources":[{"srcSet":"/static/00e384e52142e92b2ae60847f493220f/93d5d/0-11-16-smoothiesem-topo-ellipticity-and-ocean-loading.webp 147w,\n/static/00e384e52142e92b2ae60847f493220f/65bee/0-11-16-smoothiesem-topo-ellipticity-and-ocean-loading.webp 295w,\n/static/00e384e52142e92b2ae60847f493220f/984f8/0-11-16-smoothiesem-topo-ellipticity-and-ocean-loading.webp 589w","type":"image/webp","sizes":"(min-width: 589px) 589px, 100vw"}]},"width":589,"height":587}}}},{"node":{"name":"0-11-31-mesh-to-mesh-interpolation","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/30bed9583f94f1a56b42bf0848362223/c76d6/0-11-31-mesh-to-mesh-interpolation.png","srcSet":"/static/30bed9583f94f1a56b42bf0848362223/01ace/0-11-31-mesh-to-mesh-interpolation.png 275w,\n/static/30bed9583f94f1a56b42bf0848362223/a619d/0-11-31-mesh-to-mesh-interpolation.png 550w,\n/static/30bed9583f94f1a56b42bf0848362223/c76d6/0-11-31-mesh-to-mesh-interpolation.png 1099w","sizes":"(min-width: 1099px) 1099px, 100vw"},"sources":[{"srcSet":"/static/30bed9583f94f1a56b42bf0848362223/2b144/0-11-31-mesh-to-mesh-interpolation.webp 275w,\n/static/30bed9583f94f1a56b42bf0848362223/eba15/0-11-31-mesh-to-mesh-interpolation.webp 550w,\n/static/30bed9583f94f1a56b42bf0848362223/d2b16/0-11-31-mesh-to-mesh-interpolation.webp 1099w","type":"image/webp","sizes":"(min-width: 1099px) 1099px, 100vw"}]},"width":1099,"height":1042}}}}]},"changelog":{"edges":[{"node":{"fields":{"fileContent":"[\"2026.6.0\"]\nrelease_date = \"unreleased\"\nrelease_message = \"\"\"\"\"\"\n\n# Mike\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nReformulated the chain-complex code as a handful of coordinate-free algebraic\n\"moves\" (`weld`, `merge`, `split`, `separate`) built on top of algebraic\nprimitives.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nchange_id = \"gll-surface-patch-interface-reinterpolation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nImproved the algorithm for band-limited interface reinterpolation for high-order\n(>1) meshes.\n\nWhen a layered mesh is built at model order greater than one (or locally\nrefined), its interface side sets are re-snapped to the true interface geometry.\nAliasing of the interface topography by surrounding elements could result in\npinched / inverted elements with invalid Jacobians. To remedy this, the target\ninterface is now evaluated through a standalone `GllPatch` that samples the\ninterface on the side-set facet GLL nodes and reconstructs it through those\nfacets' Lagrange basis. Several performance improvements now make this viable\nfor general meshes:\n\n- A new deduplication algorithm more aggressively deduplicates horizontal\n  points, resulting in fewer queries to the high-order interpolation routines\n- Horizontal queries of a deep mesh with vertical-only deformation can now use\n  only the 1st order element edges for the reference coordinate calculation and\n  enclosing element search, while still interpolating through the full\n  high-order facets\n- Distributed meshing workflows can now work with full-mesh surface patches\n  directly, removing the need for a costly halo layer to surround each distributed\n  mesh chunk\n\nTogether we expect these developments to result in more robust handling of\nmeshes in the presence of aliased boundary topography, decreasing the occurrence\nof sporadic \"invalid Jacobian\" error messages.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFixed a regression in distributed mesh building that could imprint artifacts\non inversion gradients along mesh-chunk boundaries.\n\nMesh chunks have always been rebuilt from their unstructured form during\ninterface reinterpolation -- but previously from the chunk plus a one-element\nhalo, with the halo trimmed off afterwards. That construction pins the node\nordering inside each chunk's blocks to the ordering the global mesh induces,\nso extracting a chunk plus a halo and rebuilding it reproduces the block\nnode ordering exactly. Workflows rely on this: most notably the distributed\ngradient smoothing of the MPI inversion workflow copies the smoothed\nblock-nodal fields back into the original blocks positionally. The\nband-limited interface reinterpolation introduced with the `GllPatch` no\nlonger needs the halo for interpolation coverage and dropped it, rebuilding\neach chunk from its halo-free unstructured form instead. This reordered the\nseam-adjacent nodes inside the chunk's blocks, and the positional copies then\nput smoothed gradient values on the wrong nodes along the chunk boundaries.\nChunks are now again selected with a one-element halo that is trimmed off\nafter reinterpolation, restoring the previous node ordering while keeping the\nfull-domain patch-based interpolation.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nExtend the experimental polycube mesher with an end-to-end path from a\nsizing field to a conforming quad mesh. It lays down a\nstructured base complex, refines it with a sizing-driven 1->4 quadtree until\nevery cell meets the target element size, and resolves the resulting 2:1\ntransitions into doubling-layer templates. Supporting this are new\nchain-complex primitives: an embedded chain complex carrying reference\ncoordinates and refinement levels, a valence-generic face split, and dihedral\nframes giving canonical local coordinates for addressing chord crossings and\ntemplate application, alongside substantial performance and memory\nimprovements to the underlying refinement and chain-complex operations.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd `hypercube_element_counts` and `integrate_element_counts` to the\nexperimental polycube meshing primitives — they integrate a unit-cube sizing\nfield pulled back through the transfinite-interpolation Jacobian to size the\nstructured base complex of a hypercube. By \"base complex\" here we mean the\ncomplex that will be refined via quad / octree refinement, and made conforming\nvia template application (both existing chain complex operations).\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nLoosen tolerance in misfit statistics integration test to fix flaky CI.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusFEM\"\nchange_id = \"bugfix-spatial-gradients-2d\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nCorrects the computation of spatial gradients on 2-D meshes in the case where\nthe element geometry was irregular.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd an experimental implementation of a chain complex data structure and\nseveral related transformations for unstructured quad meshes, following\nShapero, Daniel. \"Linear-Algebraic Representation and Transformation of\nUnstructured Meshes.\" In Proceedings of the 2025 SIAM International Meshing\nRoundtable (IMR). Proceedings. Society for Industrial and Applied Mathematics,\n2025. https://doi.org/10.1137/1.9781611978575.13.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd `apply_doubling_layer` — a composite 2:1 topological transformation\nbuilt from `split_k_cells` and `merge_k_cells` — and\n`mixed_cell_topology_to_chain_complex` — a polygon-agnostic companion to\n`cell_topology_to_chain_complex` that handles mixed-element meshes\n(triangles, quads, pentagons, ...) — to the chain-complex algorithms module.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd a bind mount to persist Claude sessions between devcontainer rebuilds.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd `partition_xarray_data` to `layered_meshing.utils` — an experimental\nxarray-level partitioning utility that splits a DataArray or Dataset into\nlayers separated by linearly interpolated interfaces, derived from an\ninteger label field. Intended to eventually replace the discontinuous-mode\nbehavior of `layered_model.partition`.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd `remap_xarray_to_unit_domain` to `layered_meshing.utils` — an experimental\nboundary-conforming remap of a DataArray or Dataset slab between two bounding\nsurfaces onto the unit square (2D) or unit cube (3D). The trailing axis is\nrescaled per column so the bounding surfaces map to `t = 0` and `t = 1` and\ncarry the column's pin value at the cut; horizontal coordinates are re-labeled\nuniformly onto `[0, 1]`. Implemented as a per-column 1-D linear interpolation\nalong the trailing axis.  Composes with `partition_xarray_data` (which now\nshares the same trailing-axis lerp primitive via the private\n`layered_meshing.utils._details` module) to produce bleed-free unit-domain\nlayers for the conformal meshing pipeline.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd `ScalarSizingField` and `VectorSizingField` to the new private\n`salvus.mesh._polycube` subpackage. Both store element-sizing forward maps\n(`1/h`, in 1/m) on the unit cube with spatial dims `(\"r\", \"s\")` (2-D) or\n`(\"r\", \"s\", \"t\")` (3-D). `VectorSizingField` carries per-axis sizes along a\nlabelled `\"dim\"` trailing axis (e.g. `forward_map.sel(dim=\"r\")`).\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nUpdate C++ formatting to be consistent with the current clang-format\nrelease.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd bi- and tri-linear transfinite-interpolation `transform` / `jacobian`\nmaps to the new private `salvus.mesh._polycube` subpackage. These blend a\nhypercube's boundary charts — keyed by `(axis, sign)` — into a smooth\nvolume map: a `Chart` protocol with `LineSegment` and `BilinearPatch`\nconcrete charts, and a `Hypercube` protocol with `Square` (2-D) and `Cube`\n(3-D) blocks that validate their own watertightness on construction and\noffer named `from_edges`/`from_faces` constructors.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd bi- and tri-linear transfinite-interpolation `transform` / `jacobian`\nmaps to the new private `salvus.mesh._polycube` subpackage. These blend a\nhypercube's boundary charts — keyed by `(axis, sign)` — into a smooth\nvolume map: a `Chart` protocol with `LineSegment` and `BilinearPatch`\nconcrete charts, and a `Hypercube` protocol with `Square` (2-D) and `Cube`\n(3-D) blocks that validate their own watertightness on construction and\noffer named `from_edges`/`from_faces` constructors.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd three new chain complex operations:\n    -   `split_edges` to the chain-complex algorithms module — a vectorized\n    primitive that bisects a batch of edges at new midpoint vertices, updating\n    every incident face so the complex stays conforming.\n    - `vertex_split` to the chain-complex algorithms module — a vectorized\n    primitive that fans each selected face into a triangle fan around its own\n    new apex vertex (Shapero S4.2) — and `face_centroids` for assigning the apex\n    coordinates.\n    - `refine_quads` to the chain-complex algorithms module — a composite 1->4\n    isotropic quad refinement built from `split_edges`, `vertex_split`, and\n    `merge_k_cells`. The result is a conforming but mixed mesh; unrefined\n    neighbors of a refined edge become transition polygons.\\\n\"\"\"\n\n# Lion\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nFixed a bug in the internal paramiko patch where a failed SSH connection\nattempt (e.g. with interactive two-factor logins or transient network issues)\nwould leave the patch permanently applied. In compiled Salvus distributions\nthis broke all subsequent SSH connection attempts. The patch is now always\nreverted, is never applied twice, and gracefully handles functions whose source\ncode cannot be retrieved.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd `DistributedMesh.write_h5()` and `DistributedMesh.from_h5()` to serialize\nand deserialize a distributed mesh to and from a directory. Each rank writes\nits local mesh while rank 0 additionally writes the embedding, the global\nelement map, and a metadata file. The `dmplex` is reconstructed on read.\nReading is only supported with the same number of ranks the mesh was written\nwith.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate to allow running with matplotlib 3.11 soon.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdded justfile.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAuto-activate the correct environment in the devcontainer.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nIf verbosity >= 2 print debug output for simulations on all ranks.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nImprove cross-rank exception handling in the internal MPI helpers:\noriginal tracebacks are preserved on the failing ranks, all failing\nranks are reported together with their tracebacks, and unpicklable\nexceptions no longer risk deadlocking the exception synchronization.\n\nIn addition, a new `mpi.raise_if_any_raises()` context manager has been added\nand it is used in a few select simulation/inversion workflows.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nSpeed up the gradient post-processing step: the model-space mass matrix is\nnow computed once per element instead of once per element and parameter,\nredundant per-element map lookups and temporary allocations in the inner\nloops have been removed, nodal fields can now be attached by local element\nindex, the model-space DM is created once instead of once per physics\nblock, and a quadratic ROI lookup in the assembled path is now a hash-set\nlookup.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nSpeed up the conversion between `Mesh` and `UnstructuredMesh` in both\ndirections: `MeshBlock.global_degrees_of_freedom` and\n`Mesh.number_of_points` are now cached, `assemble_safe` uses a linear-time\nscatter instead of sorting the index array, and the migration functions no\nlonger recompute the reverse element ordering and index mappings per field,\nnor copy extracted fields twice.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nchange_id = \"trace-consistency-hardening\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nHardened the consistency checks around observed-vs-synthetic waveform traces\nso that mismatched data surfaces as an immediate, actionable error instead of\nsilently corrupting or aborting a workflow late.\\\n\"\"\"\n\n# Pat\n\n[[\"2026.6.0\".changes]]\nchange_id = \"laplacian-and-centroidal-smoothing\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd functions for performing Laplacian and centroidal smoothing on meshes.\nThese mesh smoothing routines are available under\n`salvus.mesh.algorithms.improve` and offer a computationally inexpensive way of\nimproving the mesh quality for discretizations that contain strongly deformed\nelements.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\nchange_id = \"spherical-interpolation-radial-scaling-fix\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSpherical volume models provided as Xarray datasets that have\n`geospatial_vertical_units` of `km` are now reliably rescaled to base SI\nunits during interpolation.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nchange_id = \"compute-minimum-time-step-across-meshes\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a function to compute the minimum time step across multiple meshes.\nThis is useful for ensuring that simulations are discretized on the same time\naxis.  Here's an example:\n\n```python\nfrom salvus.mesh.algorithms.unstructured_mesh.metrics import (\n    compute_minimum_time_step_across_meshes,\n)\n\n# A list of meshes for which to compute the minimum time step.\nmeshes = [\n    sn.UnstructuredMesh(...),\n    sn.UnstructuredMesh(...),\n]\n\n# Compute the minimum time step across the various meshes\ntime_step = compute_minimum_time_step_across_meshes(meshes=meshes)\n```\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusCompute\"\nchange_id = \"get-wavefield-snapshots-sampling-interval\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the ability to specify the number of wavefield snapshots to output for a\nsurface or volume wavefield. For example, suppose that one would want to output\n300 snapshots for a wavefield animations. The user can specify the approximate\nnumber of output wavefield snapshots using the `number_of_snapshots` argument:\n\n```python\np.simulations.launch(\n    ...,\n    extra_output_configuration={\n        \"volume_data\": {\n            \"number_of_snapshots\": 300,\n            \"fields\": [\"displacement\"],\n        },\n    },\n)\n```\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nThe backgrounds for entities in mesh visualization widgets are now transparent.\nThis should result in more consistent widget appearances for users that use\ndark mode in Jupyter.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusProject\"\nchange_id = \"src-rec-widget-size-slider\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a slider to mesh visualization widgets that allows for the size of sources\nand receivers to be modified.\\\n\"\"\"\n\n# David\n# Fabian\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusProject\"\nchange_id = \"event-dependent-event-configuration\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAllow event-dependent event configuration with task chains.\\\n\"\"\"\n\n# Lars\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusFEM\"\nchange_id = \"time-reduced-outputs\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd `output.time_reduced_data` — a new output group that computes per-DOF\n`max`/`min` reductions over the entire simulation time range and writes a\nsingle snapshot at the end of the run. Each entry names a field, a\nreduction, a required `criterion` (`signed`/`abs`, or a field-kind-specific\nfunctional such as `vonmises`, `frobenius`, `l2`, `pressure`, `volumetric`),\nand an optional `record` list (`value`/`time`/`state`). `signed`/`abs` on\nvector or tensor fields reduce every stored component independently\n(\"componentwise\"); all other criteria are scalar functionals defining a\nsingle extremal instant, optionally with the full field snapshotted at that\ninstant (`state`). Works for both primary fields (displacement, velocity,\nphi, …) and derived fields (strain, stress, gradient-of-displacement, …)\nacross coupled acoustic-elastic simulations. Results are written as\nmulti-component HDF5 datasets (component order recorded as metadata) rather\nthan per-component suffixed scalars. `format` (`hdf5`/`hdf5-minimal`/\n`hdf5-full`) follows the same convention as `final_time_data`: unless\n`hdf5-minimal` (the default), an XDMF sidecar is written alongside the\nHDF5 file for direct ParaView consumption. GPU (CUDA) is not yet supported\nand will raise an error at setup.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nTwo improvements to the generated Python API documentation. Classes now\ndocument their annotated instance attributes (e.g. `simulations:\nSimulationComponent` on the `Project` class), which previously did not\nappear anywhere. Additionally, class methods are no longer filtered by\nthe module-level `__all__` of interface files, which silently dropped\nthe entire method documentation of classes such as `UnstructuredMesh`.\nThis change will be followed up on our documentation website\ndocs.mondaic.com as better crosslinking between pages soon.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix spelling of disc to disk.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusCompute\"\nchange_id = \"time-loop-receiver-output-performance\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nSignificantly reduce the I/O cost of point (receiver) output during the\ntime loop. The receivers HDF5 file is now kept open across periodic\nflushes instead of being re-opened and closed each time (closing forced a\nsynchronous writeback of the whole file), and per-receiver interpolation\nweights are computed once instead of per flush. On receiver-dense\nsimulations this removes orders of magnitude of write amplification.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nRe-ordering of statements that would otherwise obscure Jacobian mesh failures\nif no exceptions but also no succesfully created mesh.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd interior_deformation_order and diagnostic_output_directory parameters to\nmesh functions; implement Jacobian validation for debugging. Automatically\nincrease interior_deformation_order if Jacobian validation fails.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nGuard against incompatible test on Darwin systems.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAdd option to skip nodal gradient assembly from elemental field to nodal field\nwith valence and mass baked in, during adjoint teardown. Exposed via adjoint\nsimulation settings and Python APIs, with legacy behavior preserved when the\noption is left unset. This can reduce adjoint post-processing time for\nworkflows that do not need the assembled gradient.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nThe MPI adjoint workflow (`run_adjoint_simulations_and_sum_gradients`,\n`compute_misfits_and_gradients_from_project`) no longer pre-assembles\ngradients in the solver. The solver emits the raw per-element gradient\ntogether with the per-element mass-matrix contributions, and\n`run_adjoint` reproduces the assembly and mass-matrix scaling in Python.\nThe assembly sums over the full connectivity, so it is also correct at\npoints shared between mesh blocks, where assembling per block only would\ndivide by partial mass contributions. The `skip_gradient_assembly`\nparameter of the MPI workflow functions has been removed; there is now a\nsingle code path.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAdd 2-D modern material support, Thomsen acoustic and elastic:\n\n- 2D meshes carrying anisotropic acoustic Thomsen parameters (`RHO`, `VP`,\n  `EPSILON`, `DELTA`) now route to a dedicated 2D parameterization in the\n  solver, with forward conversion to the 2D DHV tensor container the\n  AcousticAnisotropic physics expects.\n- Add in-plane rotation support to the 2D anisotropic acoustic path under\n  `use_new_materials`, via a new `salvus.material.orientation.ClockwiseAngle`\n  in C++ matching the existing Python class.\\\n- Add 2D elastic Thomsen support to the new C++ materials path. New\n  `salvus.material.elastic.transversely_isotropic.Thomsen2D` (no GAMMA — the\n  in-plane reduction has only one shear mode) flows through a dedicated 2D\n  elastic equivalence class hierarchy and writes to the legacy\n  ElasticAnisotropic2D field container.\n\nForward and adjoint paths are supported.\\\n\"\"\"\n\n# Christian\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix outdated default branch of downstream pipelines.\\\n\"\"\"\n\n[[\"2026.6.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate CMakePresets and CI for new OSX runners.\\\n\"\"\"\n\n# Nienke\n\n\n[\"2026.5.0\"]\nrelease_date = \"2026-05-18\"\nrelease_message = \"\"\"\nThis is a major release that brings a broad set of new features, performance\nimprovements, and quality-of-life enhancements across the Salvus ecosystem.\n\nThe Salvus API remains fully compatible with `2025.X`, and projects created\nwith a previous Salvus version can be continued with this new release.\nNote, however, that this version of Salvus requires `numpy>=2.2.0`.\n\nPlease see https://docs.mondaic.com/updates/2026 for upgrading your Python\nenvironment.\n\nOn the meshing side, layered models now support interactive\nPlotly visualizations and experimental HDF5 serialization. Additional mesh\nutilities include Exodus export, improved mesh duality with dual graph support\nfor quad and hex meshes, and significantly faster surface detection.\nThis release also introduces experimental support for chunked\nmesh building and smoothing — enabling parallel construction and handling of\nmeshes that exceed available memory.\n\nSalvusCompute now offers an experimental memory estimation tool, parallel\nJacobian computation via per-rank threading, and more detailed timing output\nincluding JSON-formatted statistics in the simulation's meta.json file.\n\nFor inversions, the L-BFGS scheme now uses less memory and disk space by\ncomputing model and gradient differences on the fly. Custom event batch\nselection can now return empty control groups, and custom mapping classes can\nbe serialized into an `InverseProblemConfiguration`. Corrupted gradient files\nare now automatically quarantined and the failing events resubmitted, allowing\ninversions to continue without manual intervention.\n\nOther notable additions include type hints in distributed wheel builds for\nimproved IDE support, variable substitution in Slurm srun arguments,\nexperimental support for the Flux job scheduler, a new attenuation model\nvisualization function, and automatic mesh quality control when adding meshes\nto a project.\n\nFor the full list of changes, please refer to the detailed changelog below.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd an experimental implementation of a chain complex data structure and\nseveral related transformations for unstructured quad meshes, following\nShapero, Daniel. “Linear-Algebraic Representation and Transformation of\nUnstructured Meshes.” In Proceedings of the 2025 SIAM International Meshing\nRoundtable (IMR). Proceedings. Society for Industrial and Applied Mathematics,\n2025. https://doi.org/10.1137/1.9781611978575.13.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAdd 2-D modern material support, Thomsen acoustic and elastic:\n\n\n- 2D meshes carrying anisotropic acoustic Thomsen parameters (`RHO`, `VP`,\n  `EPSILON`, `DELTA`) now route to a dedicated 2D parameterization in the\n  solver, with forward conversion to the 2D DHV tensor container the\n  AcousticAnisotropic physics expects.\n- Add in-plane rotation support to the 2D anisotropic acoustic path under\n  `use_new_materials`, via a new `salvus.material.orientation.ClockwiseAngle`\n  in C++ matching the existing Python class.\\\n- Add 2D elastic Thomsen support to the new C++ materials path. New\n  `salvus.material.elastic.transversely_isotropic.Thomsen2D` (no GAMMA — the\n  in-plane reduction has only one shear mode) flows through a dedicated 2D\n  elastic equivalence class hierarchy and writes to the legacy\n  ElasticAnisotropic2D field container.\n\nForward and adjoint paths are supported.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nFix a bug when releasing licenses for adjoint simulations.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd Reveal license products and fix license handling for adjoint simulations.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate the cmake presets to respect new unversioned clang toolchain.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nConvert meshes to distributed meshes.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nSimplify the parameter submodule in Salvus Material.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"layered-model-plotly-visualization\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd interactive Plotly visualizations for realized\nLayeredModel instances. The two new functions produce 2-D cross-section\nfigures for 1-D interface models and 3-D surface figures for 2-D\ninterface models:\n\n```python\nfrom salvus.mesh.layered_meshing.layered_model import plot, plot_interfaces\n\n# Plot from a realized LayeredModel directly:\nfig = plot(model)\nfig.show()\n\n# Or from a sequence of realized interfaces:\nfig = plot_interfaces(model.interfaces)\nfig.show()\n```\n\nNote: visualization of spherical models is not yet supported.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"class-serialization\"\nproduct = \"SalvusCore\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove class and function serialization logic.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"layered-model-serialization\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd experimental de/serialization routines to meshing protocols, layered\nmodels, and materials.\n\n```python\nimport salvus.namespace as sn\nfrom salvus.mesh.layered_meshing.serialization import (\n    read_from_h5,\n    write_to_h5,\n)\n\nlm = sn.layered_meshing.LayeredModel(\n    [\n        sn.material.from_params(rho=2000.0, vp=2000.0),\n        sn.layered_meshing.interface.Hyperplane.at(\n            sn.layered_meshing.interface.Depth(500.0)\n        ),\n        sn.material.from_params(rho=2500.0, vp=3000.0, vs=2200.0),\n        sn.layered_meshing.interface.Hyperplane.at(\n            sn.layered_meshing.interface.Depth(1000.0)\n        ),\n        sn.material.from_params(rho=3000.0, vp=4000.0, vs=3300.0),\n    ]\n)\n\nwrite_to_h5(filename=\"layered_model.h5\", model=lm)\n\nlm_2 = read_from_h5(filename=\"layered_model.h5\")\n```\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"chunked-meshing-format\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new experimental chunked representation of a mesh on disk.\n\nThis allows building a mesh in parallel and building meshes that\nare larger than the available memory.\n\n```python\nimport pathlib\nimport xarray as xr\nimport salvus.namespace as sn\n\nfrom salvus.project.tools.task_chains.prebuilt_workflows.mesh_from_domain_distributed.distributed_mesh_building import (  # NOQA\n    mesh_from_domain_distributed,\n)\n\ndomain = sn.domain.dim3.BoxDomain.unit()\n\nmodel = sn.layered_meshing.LayeredModel(\n    [\n        sn.material.from_params(\n            rho=xr.DataArray([0.0, 1.0], [(\"x\", [0.0, 1.0])]), vp=1.0\n        ),\n        sn.layered_meshing.interface.Curve(\n            xr.DataArray(\n                [-0.1, +0.1],\n                [(\"x\", [0.0, 1.0])],\n                attrs={\"reference_elevation\": 0.8},\n            )\n        ),\n        sn.material.from_params(\n            rho=xr.DataArray([0.0, 1.0], [(\"x\", [1.0, 0.0])]), vp=2.0\n        ),\n    ]\n)\nmesh_resolution = sn.MeshResolution(\n    reference_frequency=25.0, elements_per_wavelength=1.1, model_order=4\n)\n\nchunked_mesh = mesh_from_domain_distributed(\n    output_folder=pathlib.Path(\"chunked_mesh\"),\n    domain=domain,\n    model=model,\n    mesh_resolution=mesh_resolution,\n    sites=None,\n    min_number_of_chunks=16\n)\n\nprint(chunked_mesh)\n```\n\n```\nChunkedMesh\n  File size: 57.3 MB\n  Folder: chunked_mesh\n  Number of mesh chunks: 16\n  Number of elements: 10976\n  Model order: 4\n```\n\nAn optional `mesh_postprocessing_callback_function` can be passed to\n`mesh_from_domain_distributed` to modify each chunk and the embedding mesh\nafter meshing for custom workflows.\n\nThe chunked meshing uses shared memory to pass the embedding between multiple\nrunners on a single machine.\\\n\"\"\"\n\n\n[[\"2026.5.0\".changes]]\nchange_id = \"vars-in-additional-srun-vars\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAllow using variables in the the `additional_srun_arguments` Slurm\nconfiguration. Available variables are `{NODES}`, `{RANKS}`, and\n`{TASKS_PER_NODE}`, which will be filled automatically.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"proper-type-stubs\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nInclude type hints in the distributed wheel builds. This improves the\ntype checking and usage experience of the Salvus Python library.\n\nA good example is tab completion and docstring display in VSCode.\\\n\"\"\"\n\n\n[[\"2026.5.0\".changes]]\nchange_id = \"degree-of-freedom-stacking-along-chords\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd support for the stacking of degrees of freedom (DOFs) along a chord of\nelements.  Stacking in this context refers to re-indexing degrees of freedom\nwithin each element into tangent planes or lines. This functionality is\nsupported by `stack_along_chord` method in the\n`salvus.mesh.mesh.algorithms.dual` module.  This function returns two indexing\narrays, which contain local and global re-indexing arrays respectively. See the\nfunction's docstring for more information.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"enhanced-mesh-duality\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd support for computing dual graphs of quad and hex meshes as sparse\nadjacency matrices, along with new chord-analysis utilities. See\n`salvus.mesh.algorithms.unstructured_mesh.dual` for more details.\\\n\"\"\"\n\n\n[[\"2026.5.0\".changes]]\nchange_id = \"chunked-meshing-smoothing\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nDistributed smoothing for chunked meshes using a halo region.\n\n```python\n# Smoothing configuration.\nsc = sn.ConstantSmoothing(\n    smoothing_lengths_in_meters={\"VP\": (20, 20, 20), \"RHO\": (30, 30, 20)}\n)\nsmoothed_chunked_mesh = smooth_chunked_mesh(\n    output_folder=tmp_path / \"smoothed_chunked_mesh\",\n    chunked_mesh=chunked_mesh,\n    smoothing_config=sc,\n    # Halo width around each chunk in meters.\n    halo_width_in_meters=150.0,\n    sites={\"my_site\": task_chain_site_config},\n)\n```\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"use-multi-threading-in-solver-from-task-chains\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nForward settings for multi-threading per rank to the solver in task chains.\n\nWhen using a `TaskChainSiteConfig` each MPI rank will now use\n`max_threads_per_worker` / `ranks_per_salvus_simulation` threads.\n\nAssuming a machine with 4 GPUs, the following configuration will run one\nparallel simulation on each GPU, each using one MPI rank and 10 threads.\n\n```python\ntcsc = TaskChainSiteConfig(\n    ...\n    number_of_parallel_workers=4,\n    ranks_per_salvus_simulation=1,\n    max_threads_per_worker=10,\n    ...\n)\n```\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"serialize-mappings\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the ability to serialize custom mapping classes into an\nInverseProblemConfiguration.\n\nThis allows users to define their own mapping classes to transform between\nphysical and inversion spaces:\n\n```python\nfrom salvus.opt.mappings import Mapping\n\nclass MyCustomMapping(Mapping):\n    def __init__(self, *args, **kwargs):\n        print(\"In init\")\n        super().__init__(*args, **kwargs)\n\np += sn.InverseProblemConfiguration(\n   mapping=MyCustomMapping(\n       scaling=\"absolute\",\n       inversion_parameters=[\"VP\", \"RHO\"]\n    ),\n    ...\n)\n```\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"experimental-support-for-flux\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new executor to run Salvus on the Flux framework:\nhttps://flux-framework.readthedocs.io/en/latest/.\\\n\"\"\"\n\n\n[[\"2026.5.0\".changes]]\nchange_id = \"force-interactive-authentication\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nIf an interactive SSH login is requested, Salvus will now ensure it\nhappens, even if the initial connection attempt succeeded.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"add-exodus-writer\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImplement mesh writer for exporting Salvus meshes in the Exodus file format\n(`.e`).\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"plot-attenuation-model\"\nproduct = \"SalvusMaterial\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew salvus.material.attenuation.plot_q_model() function to visualize\nattenuation models.\\\n\"\"\"\n\n\n[[\"2026.5.0\".changes]]\nchange_id = \"speedup-find-surface\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSpeed up the find_surface algorithm in\nsalvus.mesh.algorithms.unstructured_mesh.side_sets by using a new algorithm\nbased on a mesh's facet dual graph.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"handling-corrupted-gradient-files\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a mitigation for corrupted gradient files in the HDF5 output.\n\nThe new measure will detect corrupted gradient files and move them to a\nquarantine folder inside the project attachments. The failing events are\nresubmitted during the inversion workflow by default, so the inversion can\ncontinue without interruption.\n\nOnly if the same event/model combination fails again, the user is required to\nmanually investigate or remove the files from quarantine.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"improve-project-dir-detection\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove the detection logic of a project directory. It will now raise a useful\nerror message when passing the wrong path as a project directory instead of\nsuggesting to migrate to another project revision.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"enable-empty-control-groups\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable empty control groups in an inversion when using a custom event batch\nselection. Note that this will not enfore a monotonically decreasing misfit\nfunction, and it will neither modify the trust region radius after the\nfirst iteration, because an actual reduction is not available in this case.\n\nExample:\n```\nimport typing\nimport salvus.namespace as sn\ndef my_custom_event_selection(\n    inverse_problem_configuration: sn.InverseProblemConfiguration,\n    current_iteration_id: int,\n) -> typing.Sequence[str] | dict[str, typing.Sequence[str]]:\n\n    # Always use all events, but disable the control group.\n    return {\n        \"events\": inverse_problem_configuration.events,\n        \"control_group\": []\n    }\n\n\np.add_to_project(\n    sn.InverseProblemConfiguration(\n        ...,\n        event_batch_selection=my_custom_event_selection,\n    )\n)\n```\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"run-mesh-qc-in-project\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the ability to run an automated quality control on `UnstructuredMesh`\nobjects when they are added to a project via an\n`UnstructuredMeshSimulationConfiguration`. This should allow users to catch\npotential issues with the mesh early on before running potentially expensive\nsimulations that might fail at a later stage. The same checks are now performed\nwhen a mesh is first created using the internal Salvus mesher using the\nfunction `mesh_from_domain()`. Use the `skip_validation=False` flag to enable\nthe mesh QC step.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"receiver-data-rotation-on-output\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnables using the `rotation_on_output` argument on normal `Point2D` and\n`Point3D` objects.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"add-memory-estimation-tool\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded an experimental memory estimation tool that can be used to estimate the\nrequired memory usage of a simulation before running it.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"speed-up-time-step-computation\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSpeed up the time step computation in both the solver and the mesher by binding\nthe minimum distance computation to a C++ implementation.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"timing-for-adjoint-runs\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd more detailed timing statistics to adjoint runs.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"timing-as-json\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd JSON timing output to a simulation's meta.json file for simplified\ndownstream reporting.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"parallel-jacobian-computation\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new experimental group `\"num_threads_per_rank\"` to the SalvusCompute,\nwhich controls the maximum number of threads that may be spawned from each MPI\nrank. If set, threading will be used to parallelize the computation of the\nJacobian during simulation startup, which can result in significant speedups.\\\n\"\"\"\n\n[[\"2026.5.0\".changes]]\nchange_id = \"better-startup-timing\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd experimental support for more detailed timing of simulations in\nSalvusCompute.\\\n\"\"\"\n\n\n[[\"2026.5.0\".changes]]\nchange_id = \"hessian-on-the-fly\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nReduce the memory consumption of the L-BFGS scheme and reduce the required\ndisk space. Only models and gradients that are needed to compute the\napproximate Hessian are retained in memory. Model and gradient differences are\nnow computed on the fly.\\\n\"\"\"\n\n[\"2025.1.3\"]\nrelease_date = \"2026-05-01\"\nrelease_message = \"\"\"\nThis is bug fix release for the 2025 version of Salvus.\n\nIf you can upgrade to `numpy>=2.2.X`, we recommend directly updating to\n`2026.5.0`.\n\nFor the full list of changes, please refer to the detailed changelog below.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nMPI workflows now support volumetric wavefield outputs.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"fix-bug-layer-realization\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug where layered meshing would fail during the layer realization stage\nin some edge cases.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"data-processing-validation\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nAdd an experimental data processing validation action. This can be useful to\nidentify potential issues with seismological data, which is typically\nheterogeneous (data from different networks and stations with varying\nrecording settings).\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"stabilize-asdf-processing\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nUpdate the processing that is applied to seismological data when interpolating\nthe data to the time axis of the synthetic data. This should reduce undesired\nprocessing artifacts.\\\n\"\"\"\n\n\n[[\"2025.1.3\".changes]]\nchange_id = \"fixed-optimal-transport-misfit-function-typo\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nCorrect the name of the\n`graph_space_optimal_transport_misfit_and_adjoint_source` function, which was\npreviously misspelt.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"cc-event-misfit-fix\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that was causing the validation for `EventMisfit` to fail when used\ninitialized in combination with the `cross_correlation_no_observed_data` misfit\nfunction.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\nchange_id = \"fix-layered-meshing-bug\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that would result in a failure of the layered mesher when realizing\nlayered models with layers that lie outside the domain bounds.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd a new method to the new Mesh format that allows the user to merge multiple\nblocks into a single one.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd a default retry policy to `.gitlab-ci.yml` to automatically retry jobs\nup to 2 times on transient runner/network failures (`api_failure`,\n`runner_system_failure`, `unknown_failure`).\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix a bug in the parallel distribution of materials that would trigger for\nnewer versions of `xarray`.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"fix-asdf-zero-padding\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that would cause the retrieval of seismological data to sporadically\nfail for data in ASDF format.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"fix-exodus-shell-side-sets\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that would cause side sets to not be attached when importing certain\ntypes of Exodus meshes. Previously it was assumed the side set node ordering\nfor `QUAD` elements should be applied in 2D. However, this did not consider\ndifferences in side set mappings when the mesh consisted of (3D) `SHELL`\nelements instead of (2D) `QUADS`. A check is now performed in order to ensure\nthat this mapping is consistent.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nEnsure users input domain bounds in correct order to avoid inconsistent load\nerrors.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate CMakePresets.json to unpin versions for clang.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nEnsure MPI scattering of layered models to multiple processes works correctly.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nRetiring Black in favor of Ruff.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nFix untest material qc instantiations.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nAdd a model to project when no control group is used.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd SALVUS_PRODUCTS CMake variable for selecting which products to build \\\n(e.g., -DSALVUS_PRODUCTS=license_client,utility or -DSALVUS_PRODUCTS=salvus).\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nShow better error message if importing Salvus on Windows without MS-MPI installed.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"obspy-1-5\"\nproduct = \"SalvusCore\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSupport for ObsPy >= 1.5 and SQLAlchemy >= 2. Support for lower versions is\ndropped.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCore\"\npublic_change = false\ndescription = \"\"\"\nFixed dictionaries_all_close() for lists of dicts.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCore\"\npublic_change = false\ndescription = \"\"\"\nBetter memory tracking + displaying in the various timer outputs.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nAdd more information to the log files and reduce memory for certain operations.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nValidate that the triple-quoted docstrings in the codebase use\nconsistent formatting.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nBetter missing gradients error when using the task chain based workflows.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nWhen reading a new mesh object from disk. Don't reconstruct plugin materials.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nFix a bug when trying to detect the GPUs on systems where NVIDIA-SMI could\nnot be reached.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nFix spurious test error when sometimes ipyleaflet expects an event loop.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nRemove an unnecessary mesh read during task chains simulations and\ninversions.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nMPI workflows for large-scale simulations and inversion.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nStabilize a flakey partitioning test by allowing the number of elements to be\nchosen from a set.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"fix-ocean-bottom-bug-in-project\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that occurred when meshing Cartesian domains with oceans in\nSalvusProject. In certain cases, the insertion of a doubling layer within the\nocean itself led to issues in mesh construction, which was apparent when\nrunning the Marmousi tutorial at certain frequencies. A more sophisticated test\nis now performed which dynamically adapts the ocean-bottom coarsening strategy\nin these domains.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd CLAUDE.md with project guidance for Claude Code.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nReplace pn.get_section_sf() with a new DMPlexBuildSfFromClosureAndConnectivity\nthat constructs SF leaves matching the mesh chunk's compacted_connectivity\nlayout. This ensures global-to-local scatters land in the correct dense\nlocal DOF slots rather than PETSc's internal section ordering.\\\n\"\"\"\n\n\n[[\"2025.1.3\".changes]]\nchange_id = \"bugfix-high-order-relative-interpolation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix interpolation of relative-coordinate parameters onto high-order meshes.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd a new utility class that can be used to wrap pre-computed wavelength\noracles for use within the mesh generation process.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nTemporarily revert DMPlex construction during parallel meshing due to\nperformance concerns.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd star forests for re-distributing elemental and nodal fields across ranks.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"bugfix-partition-crossing-layers\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixed a bug where crossing layers might have been added by the mesh\npartitioning algorithm.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nInitial integration of a DMPlex object with a Distributed mesh.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nSalvus NG, Python-bound solver.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdates to `ruff==0.15.8` and `mypy==1.20.0`.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix the rpath of the mpi lib required for running the MPI workflows on OSX.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix boundary attachment in distributed meshing workflow.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nRefine CI logic for release pipelines and remove Linux tests on `x86_64`.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate tests for compatibility with `numpy>=2.2` and `xarray>=2025.8.1`.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix Python paths for OSX builds.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"fix-space-dependent-smoothing-bug\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that would prevent running the inversion action `smooth_model()`\nwith a `SpaceDependentSmoothing`.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusOpt\"\npublic_change = false\ndescription = \"\"\"\nEnable model mappings for the new Mesh format.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusOpt\"\npublic_change = false\ndescription = \"\"\"\nAdd experimental `BlockModel` class that is compatible with the new native\nSalvusMesh format.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAttempt to stabilize some of the tests to prevent sporadic CI failures.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix ruff rule DOC102 errors.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"pass-data-array-to-event-data\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that would prevent users from directly passing an `xarray.DataArray`\nto an EventData object.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nAllow usage of single-component external data in combination with\n`rotation_on_output` receiver argument.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nPrevent sorting of the event list when copying the simulation output to its\nfinal destination. Ensures that event data are copied to the correct output\npath, if unsorted event lists are parsed to `p.simulations.launch()`.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix some mypy issues.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"bugfix-new-materials\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThrow a proper exception in the materials implementation in SalvusCompute\nif an unsupported model order or dimension is used.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCore\"\npublic_change = false\ndescription = \"\"\"\nAdd small convenience functions for outputting 2- and 3-D lines in a VTK\nASCII format, which is handy for visualizing chords on meshes (among other\nthings). Additionally: the 2- and 3-D tensor product -> topological permutation\nwas updated to support both VTK and PETSc conventions, with the default changed\nto PETSc for internal consistency.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nRemove link to deprecated libsalvus_utility in the wheel\ncompilation.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nRefactor and reorganize the C++ code base (part 1). Introduces\na directory re-organization as well as basic format and include linting.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nReduce optimization for huge functions on Windows. Windows\nbuilds were taking an excessively long time, primarily due to the compilation\nof acoustic/elastic hexagonal.cpp files. By adding the\n/d2ReducedOptimizeHugeFunctions flag specifically for these files, the\ncompilation time has been significantly improved.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAdd a hierarchical timer class to SalvusCore.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix some mypy errors that cropped up with a version update.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"bugfix-smoothiesem-block-propagation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug where the block elemental field was sometimes incorrectly propagated\ninto the central cylinder in smoothiesem meshes. Additionally, add the\n\"z_node_1D\" element nodal field to smoothiesem meshes to enhance backwards\ncompatibility.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusOpt\"\npublic_change = false\ndescription = \"\"\"\nFix an inconsistency in the L-BFGS computations for non-consecutive iteration\nIDs and refactor the module .\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nMake Jacobian ordering consistent between 2- and 3-D.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd experimental algorithms for chunked mesh creation and assembly.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nChange Gitlab CI cacheing strategy for linux builds.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd experimental bindings of SalvusCompute with Python.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nFix block reading and writing of receiver blocks of more than 1 block, and add\na relevant regression test. Fix a raised deprecation warning for converting\nsize-1 arrays to floats.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nImprove Mesh serialization robustness for mixed-width (data type) arrays\ninteroperating with VTK. Add unit test for VTKHDF reading of various width\nfields.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix aggressive datatype size savings when writing Mesh objects to disk: The\nVTKHDF format doesn't accept differing datatypes for connectivity and offsets,\nnor does it accept short-width integer types (like int8 or int16). The new\nserialization code now picks the smallest integer dtype that can represent both\noffsets and connectivity values, while adhering to VTK's requirements.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nPlumbing for ChunkedMeshes based on the new Mesh format, and support for\nstarting simulations from the new Mesh format (but followed upon launch) by\na cast to UnstructuredMesh).\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCore\"\npublic_change = false\ndescription = \"\"\"\nAdd back legacy implementation for rotation tensors if leading shapes are\ndifferent, add shape checks, add tests. Update LLM instructions to be better at\nrunning tests.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nPlumbing for ChunkedMeshes based on the new Mesh format, and support for\nstarting simulations from the new Mesh format (but followed upon launch) by\na cast to UnstructuredMesh).\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCore\"\npublic_change = false\ndescription = \"\"\"\nFix bug in RLE compression for large integers -- it now explicitly sets\nrelative tolerance. Fix bug in side set delamination that resulted from this,\ncreated reproducing tests and ensured they pass.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nParallelism-related improvements:\n- Set some sensible environment variables to prevent oversubscribing in\n  testing, locally and in CI.\n- Enable dmypy by default in local testing.\n- Add typing stubs for bindings.\n- Enforce ExecutionPolicies throughout tests.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nCheck that all execution policies are exposed, add AST check for ensuring\nthis.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix bug for stress tensor receiver output. Add robust checks that ensure all\npossible output fields are tested.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdhere to import order for namespace and modules.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdhere to import order for FEM and utils.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusOpt\"\npublic_change = false\ndescription = \"\"\"\nSmall fixes to the opt module:\n- Make opt model abstract base model stronger typed.\n- Modernize other types.\n- Fix a bunch of docstrings, share them from base class.\n- Make functions without arguments properties where appropriate.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd to block mesh format:\n- reader and writer.\n- lossless roundtripping to disk and back.\n- comparison functions.\n- attribute shortcut system.\n- constant nodal field collapse to and expand from scalars.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nEnable Ruff B006, fix resulting bugs.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nImplement separate inflated and compressed assembly functions to clean up\nmixed signatures. Added tests for the shapes of assembly.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFormat entire code base using Ruff, with an eye on target-version py311 (lots\nof optionals and unions removed). Lots of removed quotation marks by adding\n`__future__`'s annotations.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd example module `salvus_example_module` to showcase current Python\ndevelopment practices, and instruct LLM agents how to write code in Salvus.\nInstructions to coding agents refer to our Python Development Guide, which is\ncopied verbatim from the Wiki.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAllow the docstring parser to parse all docstrings in the codebase before\nraising any errors, using the Python 3.11 ExceptionGroup feature.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd experimental new mesh format to Salvus. For now only implemented as data\nstructures that can be created from scratch or the legacy mesh format, and does\nnot include any usage in other parts of Salvus.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nGeneric development experience updates:\n- Add support for dmypy in the local testing script.\n- Add LLM AI Agent instructions.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"experimental-and-deprecated-warnings\"\nproduct = \"SalvusCore\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd experimental and deprecated warnings to Salvus, such that users can\nidentify changing parts of the API more easily. The experimental and deprecated\nfunctions emit warnings (typically once per Python process) when such functions\nare used.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd CI and local testing checks for implementation status in Salvus.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nTemporarily build test meshes externally to Cmake on Windows to avoid CI\nfailures, s.t. we can merge new features without breaking our heads over\nWindows issues.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCore\"\npublic_change = false\ndescription = \"\"\"\nNew ability to selectively serialize imported functions when serializing\nfunctions to strings.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nPrevent overflows in the RLE encoding in very specific cases.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd detailed timings for parallel chunked meshing algorithms.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusCore\"\npublic_change = false\ndescription = \"\"\"\nAdd a timer class to aid in profiling nested and long-running workflows.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nMove to `pyproject.toml` and refactored the wheel compilation logic.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nBugfix serializing mixin materials classes.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nThe run_linting_and_testing.sh script now also checks that the changelog\nhas been changed.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nImprov types and added consistent .pyi files in wheels.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nFix a few flaky integration tests.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate Python paths for OSX.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nRefine the rules for MR pipelines to speed-up CI time.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"fix-legacy-wrapper-compute-dt\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a wrapper for estimating the time step based on the legacy function\n`UnstructuredMesh.compute_dt()`. Note, however, that this function is\ndeprecated, and it is highly recommended to use the more accurate\n`UnstructuredMesh.compute_time_step()` instead, which was introduced in\n2025.1.2.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAllow customization of the target branch for downstrream pipelines in the\nElementi repo. If defined, `ELEMENTI_TARGET_BRANCH` will overwrite the\nauto-detected target branch.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"bugfix-trial-model-rejections\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a logic error when reaching a user-defined maximum number of trial model\nrejections in an inversion. If this happens in any but the first iteration, it\nis treated as a converge criterion and the inversion will stop.\\\n\"\"\"\n\n[[\"2025.1.3\".changes]]\nchange_id = \"type-hints-in-mesh-widget\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix type hints in the mesh widget, which sometimes caused failures in\nvisualizing the simulation setup.\\\n\"\"\"\n\n[\"2025.1.2\"]\nrelease_date = \"2025-09-01\"\nrelease_message = \"\"\"\nThis is a minor release bringing in a range of improvements and bug fixes.\n\nNotable changes include the ability to accurately compute a stable time step\nin Python prior to the simulation and new customization options for\npreconditioners and data selection routines.\n\nThis release also includes various internal improvements, bug fixes, and\nenhancements to stability and performance. Please refer to the detailed\nchangelog for a complete list of changes.\\\n\"\"\"\n\n\n[[\"2025.1.2\".changes]]\nchange_id = \"bugfix-seismic-moment-computation\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the SRF reader (standard rupture format) that caused seismic\nmoments to be off by a factor 10.\n\nAll inputs from the SRF file are now converted already at the time of parsing\nthe file, and the dictionary returned by `_read_srf_file` will contain all\nquantities in SI units.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nchange_id = \"interpolation-of-utc-time-axes\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that would prevent the temporal interpolation of data with a time\naxis specified in UTC time.\n```\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nchange_id = \"extra-kwargs-for-custom-preconditioners\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable passing extra keywords arguments to a custom preconditioner callback.\n\nExample:\n```\n# Custom preconditioner function with two extra keyword arguments `alpha` and\n# `beta`.\ndef custom_preconditioner(unstructured_mesh, alpha, beta):\n    # Apply a depth-dependent scaling\n    scaling = (\n        alpha * (1.0 + np.abs(unstructured_mesh.get_element_nodes()[..., -1]))\n    ) ** beta\n    inversion_parameters = [\"VP\", \"VS\", \"RHO\"]\n    for field in inversion_parameters:\n        unstructured_mesh.elemental_fields[field] *= scaling\n    return unstructured_mesh\n\n# When passing the function to an inverse problem configuration, make sure to\n# also pass the extra keyword arguments.\nsn.InverseProblemConfiguration(\n    name=\"inversion\",\n    prior_model=\"prior_model\",\n    events=[\"event\"],\n    method=sn.TrustRegion(initial_trust_region_linf=0.1),\n    misfit_configuration=\"L2\",\n    mapping=sn.Mapping(\n        scaling=\"relative_deviation_from_prior\",\n        inversion_parameters=[\"VP\", \"VS\", \"RHO\"],\n    ),\n    preconditioner=custom_preconditioner,\n    extra_kwargs_preconditioner={\n        \"alpha\": 1.0,\n        \"beta\": 2.0,\n    }\n    job_submission=sn.SiteConfig(\"local\", 4),\n)\n```\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nchange_id = \"extra-kwargs-for-data-selection\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable passing extra keywords arguments to a custom temporal weights\nfunction.\n\nExample:\n```\ndef select_data(data_array, event, station_list, components):\n    '''\n    A temporal weights function that selects a subset of the data. It\n    includes the extra keyword arguments `station_list` and `components`,\n    specifying the components and stations that are kept.\n    '''\n    selection = [\n        (station, component)\n        for station, component in set(data_array.trace.data)\n        if (component in components and station in station_list)\n    ]\n    weights = (data_array.sel(trace=selection)) * 0.0 + 1.0\n    weights.coords[\"trace_weights\"] = (\n        (\"trace\",),\n        np.ones(len(selection), dtype=np.float64),\n    )\n    return weights\n\n# You can add this function to a project via a DataSelectionConfiguration\n# where you would additionally pass a dictionary with the extra keyword\n# arguments as so:\ndsc = sn.DataSelectionConfiguration(\n    name=\"custom_data_selection\",\n    receiver_field=\"displacement\",\n    data_selection_function=select_data,\n    extra_kwargs_data_selection={\n        \"station_list\": [\"XX.AA1.\", \"XX.AA2.\"],\n        \"components\": [\"Z\"],\n    }\n)\n```\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\ntl-expected has gotten more strict on not discarding result values. Most of the\ncases it caught are fine -- these are in tests where we want to check for side\neffects -- but we should find a better way to handle cases where the result is\ninteresting (i.e. if the inverse coordinate transform fails to converge\n_within_ the bounds of an element). Bringing in a quick mitgation now.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nchange_id = \"smoothisem-improvements\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAllow for a more ergonomic way to add topography, bathymetry, and ocean loading\nto smoothiesem meshes. In particular, a new function was added named\n`add_spherical_topography_and_bathymetry_to_model` in the\n`_recipes.smoothiesem` module which assists in adding topography to a\nsmoothiesem mesh.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nInitial test case for a new mesh format.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix CI slowdown. The issue was mostly greedy parallelism. With this fix we\nare properly forwarding execution policy threadcounts and `num_thread`\narguments.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"SalvusMesh\"\nchange_id = \"compute-time-step-python\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nImprove the Python-side computation of time steps for meshes by adding\n`UnstructuredMesh.compute_time_step`. This method accounts for spectral\nwavefield order and defaults to the Courant numbers used in SalvusCompute: 0.6\nfor 2D simulations and 0.47 for 3D simulations. The method\n`UnstructuredMesh.estimate_time_step` has also been refined to produce results\nmatching those in SalvusCompute, but still allows for computationally cheaper\nestimation of the time step.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd line rulers after column 79 and 119 to devcontainers, matching our VSCode's\n`\"editor.wordWrapColumn\": 79` and a generic wide file length limit standard.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd specific GPU configuration for the light devcontainer.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"SalvusCore\"\nchange_id = \"numpy-2\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSupport for NumPy 2.0 and later versions. Numpy 1 is also still supported.\n\nTo upgrade, please reinstall your Salvus Mamba environment following the\ninstructions on [docs.mondaic.com](https://docs.mondaic.com/updates).\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nchange_id = \"deterministic-function-order-during-serialization\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnsure that the order of dependent functions in serialized code is\ndeterministic.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix test on Windows.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nCorrect string interpolation in Salvus' logging formatter.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nchange_id = \"improved-error-reporting\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove error reporting for using task chains.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd downstream pipelines to test Elementi.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nchange_id = \"fix-model-gradient-validation\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix gradient validation tests for simultaneously testing multiple events.\n`p.actions.validation.validate_model_gradients()` will now return dictionaries\nwith the finite-difference approximation and errors of each event, as well as\nthe aggegrated gradient from all events, which is available from the key\n`cumulative`.\\\n\"\"\"\n\n[[\"2025.1.2\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd Windows builds and tests to merge request pipelines.\\\n\"\"\"\n\n[\"2025.1.1\"]\nrelease_date = \"2025-07-22\"\nrelease_message = \"\"\"\nThis release brings a range of improvements, new features, and bug fixes across\nthe Salvus ecosystem. Key public developments include a faster regular grid\nextraction for Cartesian meshes, new customization options for preconditioners\nand the trust region optimization, and a QC measures for meshes and material.\n\nFurthermore, we improved the documentation and fixed a few bugs listed below.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"asdf-speedup\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixed a bug that resulted in the waveform visualization widget and the window\npicking function to be significantly less responsive and slower for\nlarge seismological data sets.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"speed-up-reg-grid-extraction\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\n`extract_model_to_regular_grid()` is now significantly more performant for\ncartesian meshes. Since the underlying algorithm was changed, the results can\nbe slightly different compared to what was obtained with the previous version.\nThe updated function is parallelized and, by default, uses the maximum number\nof cores available on your system. You can limit the number of cores like\nthis:\n\n```python\nfrom salvus.mesh.algorithms.unstructured_mesh.utils (\n    import extract_model_to_regular_grid\n)\n\nextract_model_to_regular_grid(number_of_threads=4)\n```\\\n\"\"\"\n\n\n[[\"2025.1.1\".changes]]\nchange_id = \"custom-preconditioner\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nUsers can now pass a custom preconditioner to an\n`InverseProblemConfiguration`. Custom preconditioners have to be defined as a\ncallback function with a single input argument `unstructured_mesh`,\ncorresponding to an `UnstructuredMesh` object and must again return an\n`UnstructuredMesh` object with the custom preconditioner applied.\n\nExample:\n\n```python\nimport salvus.namespace as sn\n\n# Define a custom preconditioner that applies a depth-dependent scaling\n# to the gradient\ndef custom_preconditioner(unstructured_mesh):\n    # Apply a depth-dependent scaling\n    alpha = 1.0\n    beta = 2.0\n    scaling = (\n        alpha * (1.0 + np.abs(unstructured_mesh.get_element_nodes()[..., -1]))\n    ) ** beta\n    inversion_parameters = [\"VP\", \"VS\", \"RHO\"]\n    for field in inversion_parameters:\n        unstructured_mesh.elemental_fields[field] *= scaling\n    return unstructured_mesh\n\nsn.InverseProblemConfiguration(\n    name=\"inversion\",\n    prior_model=\"prior_model\",\n    events=[\"event\"],\n    method=sn.TrustRegion(initial_trust_region_linf=0.1),\n    misfit_configuration=\"L2\",\n    mapping=sn.Mapping(\n        scaling=\"relative_deviation_from_prior\",\n        inversion_parameters=[\"VP\", \"VS\", \"RHO\"],\n    ),\n    preconditioner=custom_preconditioner,\n    job_submission=sn.SiteConfig(\"local\", 4),\n)\n```\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"trust-region-max-model-rejections\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\n`TrustRegion` objects now accept an optional input argument to set a maximum\nnumber of trial model rejections. Once this number is exceeded, the inversion\nwill either fail or accept the final model of the previous iteration and\ncontinue with the next iteration, depending on the setting chosen by the user.\n\nExample:\n\n```python\nimport salvus.namespace as sn\n\nsn.TrustRegion(\n    max_trial_models_per_iteration=5,\n    fail_if_max_trial_models_reached=False,\n)\n```\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nExpose verbosity in `project.inversions.iterate(verbosity=...)`. Setting\n`verbosity=2` will output additional timing information on time spent after the\nsimulations have completed for tasks like summing event-dependent gradients and\nwriting the gradient to disk.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nBugfixes and API settling for the new mesh-to-mesh interpolation method in\n`mesh/tools/_details`.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"documentation-rotation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded better documentation to `UnstructuredMesh.rotate_coordinates`. It should\nnow be clear in which convention the rotations are applied, and what the units\nof the angles are.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nBugfix in json_schema.py: `_dict_to_json_schema` didn't account for\n`extra_paramiko_connect_arguments_jump_host`.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"qc-system\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd QC system to materials and meshes, accessed by the member function\nmesh.qc_test() or material.qc_test(). This will run a set of tests on the\nmesh or material and return a dictionary with possible issues of varying\nseverity. The tests are not exhaustive, but should catch common issues.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nVarious small changes:\n- Added CMake preset for coverage testing in devcontainer.\n- Bump year in the Salvus docstring.\n- Add better ASDF time subsampling checks.\n- Allow more non-endian types for HDF5 compression.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nAllow applying the adjoint of the congruence transform, used for mapping\nmaterial gradients all over the place.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nFor supported parameterizations, only write out the gradient fields that are\nrequired for the inverse problem.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\n'Break' a circular import in the tests.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"preserve-event-order\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nPreserve the order of events in project operations.\n\n`p.waveforms.get(..., events=[\"event2\", \"event1\"])` will for example\nnow return the events in the order specified by the user.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"function-serialization-logic\"\nproduct = \"SalvusCore\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixed an edge case in the serialization logic of functions\ncontaining paths on Windows.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"repr-oriented-attenuating-materials\"\nproduct = \"SalvusMaterial\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix the `__repr__` methods of the oriented and attenuating materials.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFixed the SW deploy pipelines.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nMypy 1.16.0 compatiblity + adding a few more directories.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAdded an experimental group to the solver and add the boilerplate\nto make it configurable from Python.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nComputing gradients using task chain controllers now happens on each\nnode's scratch space, only the final reduction is now a global operation\nusing the shared file system. This should significantly speed up\nthe gradient computation for large projects with many events and\nnetworked file systems.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"fix-rotated-components\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix component names for rotated receivers and HDF5 receiver file output.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"jump-host-extra-connect\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSpecial paramiko connection arguments can now be separately configured for the\ndirect connection + the jump host connection to deal with tricky cases.\n\nUsage in the site config file:\n\n```toml\n[sites.my_site.ssh_settings]\n    hostname = \"some_host\"\n    username = \"some_user\"\n    # Example: Disable different pubkey algorithms for the direct + jump host.\n    [sites.my_site.ssh_settings.extra_paramiko_connect_arguments.disabled_algorithms]\n        pubkeys = [\"rsa-sha2-512\"]\n    [sites.my_site.ssh_settings.extra_paramiko_connect_arguments_jump_host.disabled_algorithms]\n        pubkeys = [\"rsa2-sha2-256\"]\n```\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdded a local windows CMake preset.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"improve-jacobian-computation\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe computation of the Jacobians for reference -> physical element mappings has\nbeen updated and improved, which should result in speedups for the simulation\nsetup stage.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nFix a bug where gradients in coupled TTI media would be incorrectly handled.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAdd gradient tests and gradient bugfixes for acoustic and elastic thomsen\nparameters in 3-D.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAllow the legacy attenuation implementation to work with the new Salvus\nmaterials in the solver.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"bugfix-parameter-realization\"\nproduct = \"SalvusMaterial\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nBugfix for a case where realization information would be lost when copying\nsymmetric tensor components.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nElastic Thomsen + gradients + rotations added to the solver.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nRotate 3-D thomsen gradients back into the correct frame of reference.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAdd 3-D rotations for 2nd order tensors (i.e. acoustic materials) to the\nsolver.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAdd 3-D acoustic Thomsen parameterization straight to the solver.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"bugfix-anisotropic-epw\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nFix a bug that could cause a meshing failure when using anisotropic elements\nper wavelength with absorbing boundaries. The fix involved changing the\nsignature of some public-facing layered model reductions. In particular, the\nsignatures for both `get_min_wavelength_reduction_function` and\n`get_max_element_size_reduction_function` have been updated to be more explicit,\nand now directly take the reference frequency and elements per wavelength as\nparameters.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix another realization bug in material._details.parameter.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"variable-s-wave-resolution\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new model filter in\n`salvus.mesh.layered_meshing.layered_model.filters` that allows for the\nselective resolution of s-waves based on the VP vs ratio. Primarily, this\nfunction take a parameter `alpha`. If `alpha` is 0, this means that the mesh's\nresolution criterion is set only by the P-wave model, and when it is 1 it means\nthe S-wave model is also resolved to the same degree. Values between 0 and 1\nindicate partial resolution of the S-wave model, with a linear taper between\nwavelength oracles for the P- and S-wave components.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"SalvusCore\"\npublic_change = false\ndescription = \"\"\"\nBring in the first steps of the materials module on the C++ side, with a\nreference implementation for acoustic VTI.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"consistent-error-message\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\n`p.simulations.launch()` now raises a consistent and correct error\nmessage it the site requires a wall time to be set.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix mypy type checking on OSX and compatibility with `mypy > 1.17.0`.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd validation of version number and dynamic libraries for aarch64 builds.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nEnsure compatibility with Scipy 1.16.0 and validate the completeness of the\nPython environment.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"inverse-mapping-custom-scaling\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nRelax validation of the mapping class in the presence of a region of interest.\nThe parameter fields will only be checked for consistency inside the region of\ninterest. This is necessary, for instance, when using a custom scaling when\ninverting elastic parameters in a coupled medium.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"trust-region-callback\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the ability to determine the initial trust region radius in a callback\nfunction. This is useful when the desired magnitude of the update is space-\ndependent.\n\nExample:\n```python\ndef initial_radius_callback(\n    current_model: UnstructuredModel, proposed_update: UnstructuredModel\n) -> float:\n    '''\n    Simple callback function to return the step size.\n\n    Args:\n        current_model: The current model in the inversion.\n        proposed_update: The proposed model update.\n\n    Returns:\n        A scalar factor by which the proposed model will be scaled.\n    '''\n    factor = 1.0 / proposed_update.norm_inf()\n    return factor\n\ntr = TrustRegion(\n    initial_trust_region_linf=initial_radius_callback,\n)\n```\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nEnsure compatibility with `auditwheel > 6.3.0`.\\\n\"\"\"\n\n[[\"2025.1.1\".changes]]\nchange_id = \"ocean-layer-velocities\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug for Cartesian meshes where the material properties of an explicitly\ndefined ocean layer would be overwritten by a volume model.\\\n\"\"\"\n\n[\"2025.1.0\"]\nrelease_date = \"2025-05-20\"\nrelease_message = \"\"\"\nThis is a major release which brings in several important changes.\n\nLarge parts of our internal stack have been changed and improved. As a result\n**Salvus now natively supports ARM64 on Linux and macOS**, meaning it runs on\nNvidia Grace CPUs and more efficiently operates on Apple Silicon.\n\nSee [here](https://docs.mondaic.com/installation) for the installation\ninstructions.\n\nFurther notable changes include, but are not limited to:\n\n* Arbitrary rotations for any acoustic/elastic material.\n* Added support for anisotropic attenuation.\n* Meshes and model updates now default to use single precision.\n* `EventData` and `EventMisfit` objects now  use\n[xarray](https://xarray.pydata.org) data structures to represent data. This\nenables significant speedups of misfit computations and per-event data\nretrieval. Additionally, due to the new data representation, custom\ntime-and-space-dependent processing and misfit computations (e.g., in the\nfk-domain) are now supported. Check out this [this tutorial](https://docs.mondaic.com/examples/tutorials/data_analysis/structured_data_interface/tutorial)\nfor more information.\n\nAdditional new features and bug fixes are listed below.\n\n**Projects from older Salvus versions that have on-going inversions cannot be\nopened in the new version. Some misfit computations changed very slightly which\nwould affect inversions close to convergence. Please finish ongoing inversions\nusing your current installation before upgrading.**\n\nIf you have any questions or concerns about upgrading, please reach out in the\n[user forum](https://forum.mondaic.com) or contact\n[support@mondaic.com](mailto:support@mondaic.com).\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"event-dependent-gradients-auto-detect\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe option `use_event_dependent_gradients` for the trust-region method now by\ndefault uses the option \"auto-detect\". When running an inversion, the\nappropriate setting is automatically determined depending on whether or not the\nforward simulations use event dependent mesh masking.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nImprove docstrings of `SphericalChunkDomain.__init__()` and\n`UTMDomain.from_spherical_chunk()` to clarify that the former expects the\nlatitude to be specified in a geocentric system while the latter expects\ncoordinates specified in an elliptical WGS84 system.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"roi-callback-functions\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nA region of interest can now optionally be provided as a callback\nfunction that takes a single mandatory input argument `prior_model`,\ncorresponding to an `UnstructuredMesh` object and returns either an\n`UnstructuredMesh` object with a `region_of_interest` field or -\npreferred - just the numpy array of the field.\n\nExample:\n\n```\nimport numpy as np\nimport salvus.namespace as sn\n\ndef roi(prior_model):\n  f = np.ones_like(prior_model.connectivity)\n  f[prior_model.points[prior_model.connectivity][:, :, 0] > 0.5] = 0.0\n  prior_model.attach_field(\"region_of_interest\", f)\n  return prior_model\n\nmapping = sn.Mapping(\n  scaling=\"absolute\",\n  inversion_parameters=[\"VP\"],\n  region_of_interest=roi)\n```\nAlternatively, the callback function can also directly return a numpy\narray of the region of interest defined as an elemental field, like\nthis:\n\n```\nimport numpy as np\nimport salvus.namespace as sn\n\ndef roi_numpy_array(prior_model):\n  f = np.ones_like(prior_model.connectivity)\n  f[prior_model.points[prior_model.connectivity][:, :, 0] > 0.5] = 0.0\n  return f\n\nmapping = sn.Mapping(\n  scaling=\"absolute\",\n  inversion_parameters=[\"VP\"],\n  region_of_interest=roi_numpy_array)\n```.\\\n\"\"\"\n\n\n[[\"2025.1.0\".changes]]\nchange_id = \"single-precision-meshes\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\n`UnstructuredMesh.write_h5()` can now automatically determine the\nnumerical precision of the fields defined on the mesh and\nwrite out the mesh in the lowest possible precision instead\nof using the default double precision. This helps to save disk space\nwhen writing large meshes to disk and will shorten the time required\nto transfer meshes between local and remote sites.\n\nTo select this option, set the `datatype` argument to None, i.e.:\n\n```python\nmesh.write_h5(datatype=None)\n```\n\nBy default, double precision is used to retain existing behavior, i.e.:\n\n```python\nimport numpy as np\nmesh.write_h5(datatype=np.float64)\n```\n\nThe model precision of meshes built by and stored in a Salvus project\ncan be configured like this:\n\n```python\np = sn.Project.from_domain(...)\np.config.model_precision = np.float32\n```\n\nThis setting now defaults to single precision `np.float32`. Users that run the\ndouble precision Salvus binary (should only affect a small group of users)\nshould now specifically set the configuration of their project to\n\n```python\np.config.model_precision = np.float64\n```\nInteger fields such as `fluid` and `ABC_elements` are now  always stored at\nlower precision.\n\nThe write mode of meshes stored in a Salvus project can now also be configured\nproject-wide like this:\n\n```python\np.config.mesh_file_mode = \"minimal\"\n```\n\nThis now defaults to `\"minimal_fast\"`, which should significantly reduce\nthe file size of meshes in a project. To visualize the resulting project meshes\nwith Paraview, please write them out like this:\n\n```python\np.simulations.get_mesh(...).write_h5(\"mesh_for_paraview.h5\")\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nSeveral bug fixes related to structured data and\nreceiver channels:\n\n- Fix `get_waveform_data()` for receiver channels.\n- Fix `get_waveform_data_xarray()` for external data\n  with receiver channels.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"bugfix-missing-jobs\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that would lead SalvusProject to fail when attempting\nto retrieve jobs that could not be found in the internal\ndatabase.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"bugfix-custom-wavelet-not-found\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nCustom source time functions are now automatically stored within\nthe project. This fixes a bug where a custom source time function\nwould sometimes not be found anymore on machines with a temporary\nfile system because it was stored in an arbitrary directory that\ndid not exist anymore. This is also useful when copying the project\nto a different location.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nVarious quality of life improvements related to the internal handling of\nstructured data and the addition of external data to a project.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nEventMisfit objects can now optionally write out intermediate\ndata for QC.\n```python\nimport pathlib\nfrom salvus.flow.collections._detail import ExtraOutput\nextra_output = ExtraOutput(\n  data_observed_windowed=pathlib.Path(\"data_observed_windowed.h5\")\n)\nEventMisfit.get_misfit_and_adjoint_source_for_event(extra_output=extra_output)\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nAdd a progress bar for ASDF data reader and time\naxis regularization. Ensure that StationXML files\nare only read once.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"bugfix-misfit-normalization\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that prevented the use of data normalizations prior to\nmisfit computation for misfit functions without observed data.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\n`EventData` and `EventMisfit` objects now internally use `xarray.DataArray`'s\nto represent data. Callback functions to process data, compute temporal\nweights, apply normalization, and to compute misfits have been updated to\nsupport these. The existing callback functions based on `obspy.Stream` objects\nare still supported, but it is recommended to switch to the new functions as\nthey are faster and they enable more use cases.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"orientations-so3\"\nproduct = \"SalvusMaterial\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd DirectOrthonormalBasis and AzimuthDipRake materials to the orientation\nmaterials module, allowing unique orientation of orthotropic, monoclinic and\ntriclinic materials.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nRemove all old usage of structure in favor of expand, s.t. meshing works more\nrobustly.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nAdd anisotropic attenuation support to the material module.\n\n- Introduced new class for anisotropic viscoelastic materials.\n- Added function to convert isotropic Q values to anisotropic Qij tensor.\n- Added convenience function exposing existing material to numpy tensor\n  functionality.\n- Updated tests account for anisotropic attenuating materials.\n- Trim out unused code and memory from 3d elastic attenuating simulations.\n- Added `assert_equal_ignore_inf` to numpy_utils.\\\n\"\"\"\n\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAdding a new mixin for anisotropic attenuation in 3D, and modernizing existing\nanisotropic implementations (visco and elastic). Not exposed user-side yet.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"field-volume-integrals\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd functions to compute volume integrals  of arbitrary fields defined at the\nGLL points on an unstructured mesh using the Lagrangian basis.\n\n```python\nimport sympy\nimport salvus.namespace as sn\nfrom salvus.mesh import layered_meshing as lm\n\n# Polynomial order.\nn = 4\ndomain = sn.domain.dim2.BoxDomain(x0=0, x1=1, y0=0, y1=1)\n\n# Create a simple mesh to use as a test.\nmesh = lm.mesh_from_domain(\n    domain=domain,\n    model=lm.material.from_params(\n        # The symbol `v` is interpreted by the layered mesher as vertical,\n        # agnostic of the coordinate system / dimensionality of the mesh.\n        rho=sympy.symbols(\"v\"),\n        # And something funky to give the integration algorithm a run for its\n        # money.\n        vp=0.5 + 0.1 * sympy.sin(sympy.symbols(\"v\") * 16),\n    ),\n    mesh_resolution=sn.MeshResolution(\n        reference_frequency=10.0,\n        elements_per_wavelength=2.0,\n        model_order=n,\n    ),\n)\n\n# Symbolic integral of the function f(x,y) = y, evaluated over the domain\n# [0,1], [0,1]\nintegral_rho = sympy.integrate(\n    sympy.symbols(\"y\"),\n    (sympy.symbols(\"x\"), 0, 1),\n    (sympy.symbols(\"y\"), 0, 1),\n)\nintegral_vp = sympy.integrate(\n    0.5 + 0.1 * sympy.sin(sympy.symbols(\"y\") * 16),\n    (sympy.symbols(\"x\"), 0, 1),\n    (sympy.symbols(\"y\"), 0, 1),\n)\nintegrals_exact = {\"RHO\": float(integral_rho), \"VP\": float(integral_vp)}\n\n# Now using the new methods on meshes\nintegrals_gll = mesh.compute_volume_integrals(fields=[\"RHO\", \"VP\"])\n\nfor field in integrals_gll:\n    print(\n        f\"Integrals of {field} using:\\n\"\n        f\"\\tGLL points:           {integrals_gll[field]:.7e}\\n\"\n        f\"\\tSymbolic integration: {integrals_exact[field]:.7e})\"\n    )\n```\\\n\"\"\"\n\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSwitch out devcontainer image for `dev-light`: multi-architecture.\n\nPlease be aware that externals now live in `/opt/salvus/dev-light`.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = true\nbreaks_existing_api = false\npart_of_stable_api = true\nchange_id = \"extrude-side-sets-with-fields\"\ndescription = \"\"\"\nThe method to extrude a side set on a 3D mesh now retains all field\nvalues and also works for higher-order meshes.\n\n```python\nimport numpy as np\n\nimport salvus.namespace as sn\n\ndomain = sn.domain.dim3.BoxDomain(\n    x0=-0.5, x1=0.5, y0=-0.5, y1=0.5, z0=-0.5, z1=0.5\n)\n\nmesh = sn.layered_meshing.mesh_from_domain(\n    domain=domain,\n    model=sn.material.from_params(vp=1.0, rho=1.0),\n    mesh_resolution=sn.MeshResolution(\n        reference_frequency=5.0,\n        elements_per_wavelength=2.0,\n        model_order=4,\n    ),\n)\n\noffsets_scalar = np.array([0, 1.0, 2.0, 3.0])\noffset_direction = np.array([0, 0, -1])\noffsets = offset_direction * offsets_scalar[:, None]\n\n# Will not retain elemental nodal fields like VP\nnew_mesh = mesh.extrude_side_set(\n    \"z0\", offsets=offsets\n)\n\n# Any manually creted mesh needs to be parsed for side sets manually.\nnew_mesh.find_side_sets(mode=\"cartesian\")\n\n# Show the final combination\nnew_mesh + mesh\n```\n\nTo retain elemental nodal fields, one needs to average/downcast these fields to\nonly vary per element.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAllow devcontainer configuration key removal in dictionary merge.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nFix missing widget methods for material plug-ins.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nCentralize all devcontainer configurations.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nFix TestUtilities on ARM systems.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nAdd (and test) representation methods for realized parameters in\nSalvusMaterial.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"high-fidelity-q-cpu\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvusCompute can now account for spatial variation of acoustic and elastic\nattenuation parameters (Qmu, QKappa) across elements when running on CPUs,\nresulting in higher fidelity modelling for attenuating media.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nSmall changes to the attenuation and elastic physics:\n- Pass model around as well when calling `mesh->SetupTopology`, so that we can;\n- Pass model around as well when calling `mesh->AddElementLabels`, so that in\n  a later MR we can;\n- Check elastic attenuation meshes early for anisotropic attenuation (in\n  `AddElementLabels`), and exceptions are raised if attenuation parameters are\n  inconsistent;\n- Two new utility algorithms: `Any` and `All`;\n\nAlso added GetAnisotropicPerturbation and SetAnisotropicPerturbation to the 2D\nelastic anisotropic mixin -- we didn't support attenuation in the 2D case yet.\nThese were not present yet. This functionality isn't enabled yet for users.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMesh\"\nchange_id = \"side-set-normals\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded a function that computes the normal vectors of element GLL points to a\nside-set bordering those elements.\n\n```python\nimport numpy as np\n\nfrom salvus.mesh.algorithms.unstructured_mesh import side_sets\nfrom salvus.mesh.algorithms._generators import spherical\n\nmesh = spherical.cubed_sphere_chunk_3d_range(\n    r_inner=25, r_outer=30, nelem=2, element_count_rad=3\n).get_unstructured_mesh()\n\nmesh.find_side_sets_enclosing(mode=\"spherical_chunk\")\n\nelements_r0, _ = mesh.side_sets[\"r0\"]\nmask = np.zeros((mesh.nelem,), dtype=np.bool_)\n\n# One could set more elements in the mask to True, but since those won't border\n# the side set, there won't be any normals computed.\nmask[elements_r0] = True\n\nnormals = side_sets.compute_normal_vectors_towards_side_set(\n    mesh, {\"r0\": mask}, split_per_mask=False, outward_pointing=True\n)\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMesh\"\nchange_id = \"sideset-between-masks\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd an algorithm to add a side set between two elemental masks.\n\n```python\nfrom salvus.mesh.algorithms.unstructured_mesh import side_sets\n\n# Some 2- or 3-D mesh.\nimport salvus.namespace as sn\nfrom salvus.mesh import layered_meshing as lm\nn = 1  # polynomial order\ndomain = sn.domain.dim2.BoxDomain(x0=-0.5, x1=0.5, y0=-0.5, y1=0.5)\n\n# Create a simple mesh to use as a test. Let parameters vary only in a\n# single direction so that we know their gradients in advance.\nmesh = lm.mesh_from_domain(\n    domain=domain,\n    model=lm.material.from_params(\n        vp=1., rho=1.\n    ),\n    mesh_resolution=sn.MeshResolution(\n        reference_frequency=10.0,\n        elements_per_wavelength=1.0,\n        model_order=n,\n    ),\n)\n\n# Mask all X coordinates larger than 0.0\nmask_A = mesh.get_element_centroid()[:, 0] > 0.0,\n# Mask all Y coordinates smaller than 0.0\nmask_B = mesh.get_element_centroid()[:, 1] < 0.0\n\n# Create a sideset between those two masks\nside_set = side_sets.create_side_set_between_masks(\n    mesh,\n    mask_A=mask_A,\n    mask_B=mask_B,\n)\n\n# And add it to the mesh\nmesh.side_sets[\"my_new_side_set\"] = side_set\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\nchange_id = \"elastic-moduli-rename\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nRenamed parameters of isotropic materials in elastic and acoustic case:\n- The shear modulus in all materials (except Lamé's parameters) are now named\n  G, to be consistent with EngineeringConstants of lower order symmetries.\n- Any material that had different variations for 2D and 3D, now has 3D as the\n  default case without any extra indications (i.e. removend the `3D` appendix),\n  while 2D materials remain special cases of those with differently named\n  parameters, e.g. `V_2D`.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nImprovements to the testing of materials:\n- Added integration tests for oriented materials\n- Better random testing for materials which properly propagate tolerances.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\nchange_id = \"symmetric-engineering-constants\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded Cubic and Hexagonal engineering constants materials.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\nchange_id = \"material-widgets\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded pretty `_repr_html_()` methods to the materials for Jupyter widgets.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"oriented-materials\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded experimental features to orient anisotropic materials in\n`sn.materials.orientation`, and methods to convert these materials to form\ncompatible with SalvusCompute.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"block-data-cube\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe method `get_data_cube` has been deprecated and become more performant by\ninternally using `get_waveform_data_xarray`. Passing an index to the\n`get_data_cube` is removed from the documentation, as this was never possible.\nTypical usage of get_data_cube should be replaced by\n`get_waveform_data_xarray`.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nCreate a copy for symmetric material parameters.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nMove Salvus repository to Mondaic/Code.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"extract-json-schemas\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded utilities to acquire JSONSchemas for the definitions of SalvusExecutors.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"immutable-project-configuration\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nA project's configuration is now no longer mutable if the project contains at\nleast one simulation configuration.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nEnabled general inversions using task chains. Src/rec cutouts do not\nwork yet.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"queues-for-local-task-chains\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nMore stable distribution of task chains across runners on a single node.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"add-xarray-data-to-project\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nExternal data stored in an xarray object can now directly be saved to a\nproject.\n\n```python\nimport xarray as xr\n\nds = xr.Dataset(...)\n\n# Adds the data + the event object to a project.\nproject.waveforms.add_external(\n  data_name=\"observed_data\",\n  event=event.event_name,\n  data=ds,\n  add_event_to_project=True\n)\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"materials-to-sim-config\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nHomogeneous materials can now be directly passed to `SimulationConfiguration`\nobjects:\n\n```python\nmaterial = sn.material.from_params(\n    rho=1500, vp=1875\n)\n\nsc = sn.SimulationConfiguration(\n    name=\"sandstone\",\n    model_configuration=material\n    ...\n)\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSerialize (nested) sets and tuples in closures.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"check-for-duplicate-receiver-ids\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe receiver ids are now validated to not contain duplicates upon\ninitialization of a `sn.ReceiverBlock` object. This used to only raise an\nexception upon running a simulation - now it fails faster.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"task-chain-runner-resilience\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe task chain runner workflows can now recover, even if one of the local task\nchain runners (e.g. the process coordinating the different runners on one node)\ncrashes.\\\n\"\"\"\n\n\n[[\"2025.1.0\".changes]]\nchange_id = \"oriented-materials-2d\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded experimental support for 2D material orientations.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"preserve-order\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nPreserve receiver order for the extra output and the adjoint sources.\\\n\"\"\"\n\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nWait a few seconds for Windows to release file locks before attempting to\ndelete files of finished simulations.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\nchange_id = \"material-pretty-repr\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded pretty `__repr__()` methods to the materials and parameters for easy\nobject display.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd license server availability integration test.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"new-extra-output-callback-function\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `MisfitConfiguration` now takes an optional\n`extra_output_callback_function` argument that can be used to write out\nquality control information during the misfit computation.\n\n```python\ndef get_extra_output(\n    *, event_misfit: sn.EventMisfit, simulation_configuration_name: str\n) -> ExtraOutput | None:\n    # In this example we only desire the output for \"event_b\"\n    if event_misfit.event_name != \"event_b\":\n        return None\n\n    # If this event is encountered during the misfit computation\n    # it will write the observed processed data to that file.\n    return ExtraOutput(\n        data_observed_processed=pathlib.Path(\"data_observed_processed.h5\")\n    )\n\nmc = sn.MisfitConfiguration(\n    ...\n    extra_output_callback_function=get_extra_output\n)\n\n# Proceed as usual\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"bugfix-slurm\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixing two bugs: The first prevented using certain combinations of job array\nsizes in Slurm while limiting the number of jobs in a job array that can run in\nparallel. The second causes a failure if Slurm reported non-consecutive job ids\nin the job array status.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"project-temp-files-in-project\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nTemporary files created by SalvusProject are now temporarily stored in the\nproject file structure. This avoids issues on systems with small `/tmp`\ndirectories.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"updated-from-bounds-domain-initializer\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `.from_bounds()` constructor of the 2-D and 3-D `BoxDomain`'s has been\nexpanded to support simplified usage:\n\n```python\n# Domains starts at a left/bottom corner of (0/0).\nd_2 = domain.dim2.BoxDomain.from_bounds(\n    x=22.0, y=33.0\n)\n# Also possible to specify the lower bounds.\nd_2d = domain.dim2.BoxDomain.from_bounds(\n    x=(-2, 22.0), y=(-3.3, 33.0)\n)\n# In 3-D.\nd_3d = domain.dim3.BoxDomain.from_bounds(\n    x=22.0), y=33.0, z=44.0\n)\nd_3d = domain.dim3.BoxDomain.from_bounds(\n    x=(-2, 22.0), y=(-3.3, 33.0), z=(-4.4, 44.0)\n)\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAllow gradients to be computed for model and simulation polynomial orders of\n7.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nA few bugfixes for attenuation materials.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nSilence the SQLAlchemy warning that we need to change things when migrating to\nSQLAlchemy 2.0.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUsing temporary paths for a test to fix sporadic failures on Windows.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nHierarchically find docstrings from parent classes if required and in general\nimproved doc parsing/generations.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"spatial-dispersion-error-estimations\"\nproduct = \"SalvusFEM\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded a few new utility functions to help estimate spatial dispersion errors\nof simulations.\n\n```python\n>>> from salvus.fem import error_estimations\n\n# Estimate the spatial dispersion error per cycle.\n>>> error_estimations.estimate_spatial_dispersion_error_per_cycle(\n...     p=4,\n...     elements_per_wavelength=2.0\n... )\n4.6692585388669274e-05\n\n# Given an existing simulation polynomial order, and a number of elements per\n# wavelength, estimate how many elements per wavelength are needed to achieve\n# the same accuracy with a different polynomial order.\n>>> error_estimations.estimate_epw_for_new_p(\n...     original_p=4,\n...     original_epw=1.5,\n...     new_p=7\n... )\n0.6858925744742578\n\n# Estimate the required elements per wavelength to achieve a certain max\n# spatial dispersion error for a given number of cycles/propagating\n# wavelengths.\n# This example assumes one wants to propagate a wavefield for 100 cycles with\n# a max error of 1%:\n>>> error_estimations.estimate_epw_for_simulation(\n...     p=4,\n...     number_of_cycles=100.0,\n...     acceptable_error=1e-2\n... )\n1.8183856099191276\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nBugfix for the local task chain runner for only running one chain per node.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nMove the paths.py file from flow to _core.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"better-function-serialization\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImproved function serialization and deserialization in Salvus.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nAdded an extra test for the adjoint source computation.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"disable-numba-jit-cache\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nIntroduced a new `SALVUS_DISABLE_NUMBA_CACHE` environment variable to\noptionally disable the numba file cache on problematic systems. Please set it\nto `\"1\"` to disable it. This results in slightly longer import times of Salvus\nbut should have no other negative effects.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"use-rtld-deepbind-for-lazy-symbol-loading\"\nproduct = \"SalvusCore\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd `RTLD_DEEPBIND` to the dynamic loader flags to protect salvus from global\nsymbol exports done by third-party dependencies.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"anisotropic-elements-per-wavelength-per-layer\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `MeshResolution` object now allows users to specify the desired\nelements per wavelength per dimension and per layer. For example, in a\n2-D 2-layer model one could specify:\n\n    - [(1.0, 2.0), (2.0, 4.0)] to request, in the first layer, 1.0\n      element per wavelength in the horizontal direction and 2.0 in the\n      vertical direction, and in the second layer, 2.0 elements per\n      wavelength in the horizontal direction and 4.0 in the vertical\n      direction.\n\nWhile in a 3-D 2-layer model one could specify:\n\n    - [(1.0, 1.0, 2.0), (2.0, 2.0, 4.0)] to request, in the first\n      layer, 1.0 element per wavelength in _both_ horizontal directions\n      and 2.0 in the vertical direction, and in the second layer, 2.0\n      elements per wavelength in _both_ horizontal directions and 4.0\n      in the vertical direction.\n\nBroadcasting rules in 2-D, where values for not all dimensions or layers are\nspecified, are as follows:\n\n    - 1.0 => 1.0 elements per wavelength in all dimensions for all\n      layers.\n    - (1.0, 2.0) => 1.0 elements per wavelength in the horizontal\n      direction, 2.0 in the vertical direction, for all layers.\n    - [(1.0, 2.0), (2.0, 4.0)] => That which is described in the 2-D\n      example above, with the additional comment that the last entry\n      (2.0, 4.0) will be used for all subsequent layers beyond 2.\n\nBroadcasting rules in 3-D, where values for not all dimensions or layers are\nspecified, are slightly different:\n\n    - 1.0 => 1.0 elements per wavelength in all dimensions for all\n      layers.\n    - (1.0, 2.0) => 1.0 elements per wavelength in _both_ horizontal\n      direction, 2.0 in the vertical direction, for all layers.\n    - [(1.0, 2.0), (2.0, 4.0)] => That which is described in the 3-D\n      example above: note that the _horizontal_ direction is broadcast\n      to become (1.0, 1.0, 2.0) and (2.0, 2.0, 4.0) respectively. The\n      last entry (2.0, 4.0) will be used for all subsequent layers\n      beyond 2, with the same horizontal broadcasting rules applied.\n\nThe corresponding dimensions to each of the elements per wavelength are\nindependent of the coordinate system, and simply reference horizontal\nand vertical directions, respectively. Coordinate names will always be\nalphabetical, so:\n\n    - in 2-D: x, y\n    - in 3-D: x, y, z\n    - in 2-D spherical: latitude, radius\n    - in 3-D spherical: latitude, longitude, radius\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"topography-wavefield-adaptive-meshes\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nInterface topography and 3-D model are now handled properly within the\nexperimental `create_smoothiesem_mesh`.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"rotate-wavefield-adaptive-meshes\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe latitude of longitude of a source can now be passed to the experimental\n`create_smoothiesem_mesh`. This will rotate the mesh so that it is centered at\nthe source location.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"higher-order-wavefield-adaptive-meshes\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug where wavefield adaptive meshing would fail for model order > 1.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"wavefield-adaptive-meshes\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds an experimental implementation of wavefield adaptive meshes for use in\nspherical domains, similar to those presented in \"Accelerating numerical wave\npropagation using wavefield adapted meshes. Part I: forward and adjoint\nmodelling\", van Driel et. al, 2020. This experimental implementation does not\nyet include sources located away from the geographic poles, surface topography,\nor model orders >= 1.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"expand-feasible-set-for-interlayer-optimizer\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nIncrease size of the feasible set for interlayer optimization (to from 1 to 50\ntimes the proposed number of elements in the current layer), in response to a\nuse case where the previous default (from 1 to 20 times the proposed number of\nelements in the current layer) was too small.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdds a commit that missed the merge of the MR which fixes a potential typing\nissue when using fp32 model.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nDo not compile static libstdc++ when using clang as a CXX compiler. This was\ncausing a crash at runtime in some stdlib functions in the Python bindings. We\ndo not deploy with Clang currently so noncompliance with manylinux is not an\nissue here, but it does affect devcontainer-light users.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nFix an edge case where the structuring of analytic and discrete parameters\ncould cause an xarray to be assigned to an AnalyticParameter's representation\ntype prior to a call to sidecast.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"speed-up-mesh-to-mesh-interpolation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds a new experimental function `interpolate_mesh_to_mesh` within\n`salvus.mesh.tools.interpolate_mesh_to_mesh` which performs mesh-to-mesh\ninterpolation between Cartesian meshes using a new optimized algorithm.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFixed an issue on OSX where the aggressive loading of symbols in reference\nshared libraries (i.e. MPI) could cause a runtime crash due to conflicting\nversions.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"speed-up-get-rotation-matrices\"\nproduct = \"SalvusMaterial\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds some memory optimizations that improve the performance of the\n`get_rotation_matrices` function, which should be noticeable when working with\nlarge arrays of oriented materials.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"add-congruence-transform\"\nproduct = \"SalvusUtils\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds a new C++ binding to compute the congruence transform of the matrix b by a,\ndefined by aba^t. This function is handy when rotating tensor quantities, in\nwhich case a represents a rotation matrix. Support for both single and batched\ntransforms exist, with the latter taking an optional `ExecutionPolicy` argument\ngoverning parallelism over the batched dimension.\n\nThis function is now used as part of the rotation routines for tilted\ntransversely isotropic media, resulting in a significant (> 2x) speedup for\nlarge models.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nMinor compilation/building fixes.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix aarch64 gcc compile.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nMinor compilation fixes.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"faster-receiver-attachment\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nReceiver attachments for very large number of receivers is now significantly\nfaster.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"parallel-get-enclosing-elements\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded a parallel version of the `get_enclosing_elements` function enabling\nvery significant speedups of a number of algorithms.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"improve-performance-of-high-order-interface-interpolation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImproved the performance of higher-order mesh re-interpolation via the\nintroduction of an approximate algorithm and other improvements. For large\nmeshes, the new default settings can give order-of-magnitude improvements in\nperformance for 4th-order meshes. By default, the interpolation of surface\ndeformation to the interior of a domain is now done linearly, rather than at the\nmodel order of the mesh. This is sufficient for the majority of cases. If the\nresulting mesh has geometric issues (like invalid Jacobians), increasing the\n`_interior_deformation_order` argument to the `MeshingProtocol` to match the\nmesh's model order may help create a valid mesh with smoother internal\ndeformations. The new algorithms are only considered for Cartesian meshes.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"fix-typing-bug-intralayer-vertical-refine\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixes a bug which could cause a typing error when `IntralayerVerticalRefine()`\npolicies were selected.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusUtils\"\npublic_change = false\ndescription = \"\"\"\nUse an einsum in place of a `@` triple product when rotating tensors -- gives a\nsignificant speedup.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"add-material-plugins-module\"\nproduct = \"SalvusMaterial\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new module `salvus.material.plugins` which houses additional functionality\nfor extending material classes. To introduce this functionality, the\n`salvus.materials.plugins.with_approx_anisotropic_acoustic_oracle` has been\nintroduced. When passed a Material type, this plugin will overwrite the\ncomputation of anisotropic acoustic wavelength oracles with a simpler approach\nbased on velocities along and perpendicular to the symmetry axes, as opposed to\nthe default which solves an Eigenvalue problem on the acoustic elastic tensor.\nThe benefit of this approximation is a significant performance gain during\nmeshing and model partitioning, most notably for large models.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"bugfix-for-permuted-periodic-boundaries\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nBugfix for the experimental periodic boundaries where a permutation of the\nconnectivity was required when periodization occurred. This allows for the\nproper periodization of more complex meshes, i.e. those which are not just built\nfrom a single structured element block. Permutations for 3-D meshes are not yet\nimplemented, and attempting to make such a mesh periodic will result in an\nerror.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"performance-improvements-in-salvus-mesh\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSeveral performance improvements were implemented during the mesh generation\nprocess which should be visible when using large model files which are mutually\naligned to a common coordinate grid.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdded some extra QOL changes affecting \"periodic-boundary-conditions\".\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"periodic-boundary-conditions\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = true\ndescription = \"\"\"\nUpgrades the experiemental implementation of periodic boundary conditions to\nalso support 2-D meshes. Additionally, changes the required argument to\n`periodic_axes` from `periodic_axes` to better reflect the intended usage. Note\nthat there are several caveats that must be considered when using this feature\nand it should be considered experimental. For this reason, we recommend you to\nreach out on the Salvus support forum if you plan to use it.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"mesh-masking-utility\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nIntroduces a new function `mesh.utils.create_mask_from_threshold` which creates\na point-wise mask based on threshold bounds defined by a set of materials. For\ninstance:\n\n```python\ncreate_mask_from_threshold(\n    mesh,\n    sn.material.from_params(rho=1.0, vp=1.0),\n    sn.material.from_params(rho=None, vp=1.5),\n)\n```\n\nwill create a masking array of shape `(mesh.nelem, mesh.nodes_per_element)` that\nis True where vp is between 1.0 and 1.5 and rho is between 1.0 and infinity. If\nthe mesh is in an alternative parameterization to that defined by the threshold\nvalues an attempt will be made to first transform the mesh's parameterization\ninto that of the threshold bounds.\n\nThis functionality is useful for, among other things, selecting features in a\nmesh to freeze during an inversion, etc.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"several-new-elastic-isotropic-parametrizations\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nIsotropic elastic materials can now be parameterized in terms of:\n\n  - density, Young's Modulus, Shear Modulus\n  - density, Young's Modulus, Poisson's Ratio\n  - density, Shear Modulus, Poisson's Ratio\n\nAll of these parameterizations are available within the\nmaterial.elastic.isotropic module, and can be instantiated in either 2 or 3\ndimensions.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix spurious error when testing `get_enclosing_elements` from\n`salvus.mesh.algorithms.unstructured_mesh.utils`. It looks like this was caused\nby the Numba JIT compiling of a gufunc (`mesh.__init__.nearest_vertical`) which\nwas then passed as an argument to `_get_enclosing_elements`. This function has\nalso now been marked as deprecated for a future release, as its\nimplementation should be generalized to consider physical coordinates and not\njust reference coordinates.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nRemove the call to `Write()` from\n`ProgressReported::UpdateProgressOfLastTask()`, as this was causing a race\ncondition in the progress reporter tests. To retain legacy behavior, `.Write()`\nis now called explicitly after each update to the progress reporter throughout\nthe SalvusCompute codebase.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nIntegrate the Reveal license client into the builds for Shearwater.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate copyright headers to 2025 and move tests out of source tree.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nImprove the robustness of an integration test for cancelling jobs.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpgrade to black `25.1.0` and mypy `1.15.0`.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nFix a bug in the re-implementation of the inverse coordinate transformation.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"upgrade-python-dependencies\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnsure compatibility with the latest versions of `scipy` (1.15.0),\n`matplotlib` (3.10), and `mypy` (1.14).\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"matplotlib-3-10\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd support for matplotlib `3.10` and maintain backward compatibility with\nmatplotlib `>=3.5.1`.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"coupled-anisotropy\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable coupled anisotropic simulations that mix parameterizations in tensor and\nvelocities.\n\nIt is now possible, for instance, to have an isotropic fluid layer\nparameterized in `VP` and `RHO` and an anisotropic elastic medium parameterized\nin Cij within the same mesh.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd linting with ruff to the CI and fix job rules for scheduled pipelines.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nFix a bug in the re-implementation of the GLL Jacobians.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"roi-in-relative-parameterizations\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nIgnore parameter fields outside the region of interest when scaling by relative\ndeviations from the prior.\nThis is relevant for inverting elastic parameters in coupled media, where some\nfields (e.g. `VS`, `Cij`) are non-zero only in the elastic domain.\n\nPreviously, an error would have been raised when inverting for relative changes\nin VS in coupled media, even if the region of interest targets only the elastic\ndomain.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"enable-anisotropic-coupled-inversions\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable gradient computations in coupled fully anisotropic elastic and isotropic\nacoustic media. Mixing parameterizations of Cij in the elastic domain and rho,\nvp in the acoustic domain was previously not supported.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"inversion-component-logging\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nReduce the logging output of the inversion component for reporting on ongoing\ntasks. Unless the `ping_interval_in_seconds` is explicitly set in\n`p.inversions.iterate()`, unfinished tasks will not be logged multiple times.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"courant-number-in-wsc\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the ability to explicitly set the Courant number in the\nWaveformSimulationConfiguration, which will be used to compute the time step of\na simulation.\n\nExample:\n```python\nwsc = WaveformSimulationConfiguration(\n    end_time_in_seconds=2.0,\n    courant_number=0.5,\n)\n```\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix CI rule to detect C++ changes and a failing test.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nEnable aarch64 builds and deploy in the CI.\\\n\"\"\"\n\n[[\"2025.1.0\".changes]]\nchange_id = \"add-project-from-mesh\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds a `Project.from_mesh` to create project from mesh, so that you do not\nneed to specify a domain first.\\\n\"\"\"\n\n\n[\"2024.1.3\"]\nrelease_date = \"2025-01-15\"\nrelease_message = \"\"\"Minor bugfix release with changes as listed below.\"\"\"\n\n\n[[\"2024.1.3\".changes]]\nchange_id = \"bugfix-inversion-with-event-dependent-mesh-masking\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that prevented the use of event dependent mesh masking in\ninversions outside of task chains.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nchange_id = \"bugfix-time-axis-precision\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug where explicitly setting time axis in the simulation by means of\n(auto) start time, time step, and end time does work in the simulation, but not\nthe data retrieval, leading to an assertion error when accessing simulated\ndata.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nchange_id = \"support-for-modern-paramiko-versions\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvus now supports the as of now latest version 3.5.1 of Paramiko.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nSilence the SQLAlchemy warning that we need to change things when migrating to\nSQLAlchemy 2.0.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nchange_id = \"improved-task-chain-performance-reporting\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImproved perforrmance reporting for task chain based workflows.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nchange_id = \"ld-library-path-flexibility\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe LD_LIBRARY_PATH can now be overwritten for local exectutors. This is useful\nwhen the Salvus binary is not in the default path or when one wants to use\na non-standard MPI.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nBugfix for the local task chain runner for only running one chain per node.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nchange_id = \"project-attachments\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded a new attachment component to Salvus project to allow for attaching\narbitrary files.\n\nCan be used for notes, images, or other files that are relevant to the project.\n\n```python\n# Attach something. By default most things must be passed as bytes.\np.attachments.add(\n    name=\"document.pdf\",\n    content=b\"...\",\n    description=\"An optional description\"\n)\n\n# For some file types strings, ...\np.attachments.add(\n    name=\"my_note.txt\",\n    content=\"This project is super interesting.\"\n)\n\n# ... and dictionaries are also supported.\np.attachments.add(\n    name=\"info.json\",\n    content={\"some\": \"content\"}\n)\n\n# Retrieve the attached files again.\np.attachments.get_content(\"document.pdf\")\np.attachments.get_content_str(\"my_note.txt\")\np.attachments.get_content_dict(\"info.json\")\n\n# Delete them.\np.attachments.delete(\"my_note.txt\")\n\n# Get a list of all available attachements.\np.attachments.list()\n\n# Retrieve some meta data for an attached file.\np.attachments.get_details(\"document.pdf\")\n```\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nchange_id = \"mix-side-set-and-non-side-set-receivers\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd support in SalvusProject for combining side-set and point receivers in the\nsame event.\\\n\"\"\"\n\n\n[[\"2024.1.3\".changes]]\nchange_id = \"bulk-modulus-parameterization-for-acoustic-materials\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nIsotropic acoustic materials can now be parameterized in terms of bulk modulus\nand density.\n\n```python\nimport salvus.namespace as sn\n\nsn.material.acoustic.isotropic.BulkModulus.from_params(rho=1500, kappa=6e9)\n```\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix spurious error when testing `get_enclosing_elements` from\n`salvus.mesh.algorithms.unstructured_mesh.utils`. It looks like this was caused\nby the Numba JIT compiling of a gufunc (`mesh.__init__.nearest_vertical`) which\nwas then passed as an argument to `_get_enclosing_elements`. This function has\nalso now been marked as deprecated for a future release, as its\nimplementation should be generalized to consider physical coordinates and not\njust reference coordinates.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nRemove the call to `Write()` from\n`ProgressReported::UpdateProgressOfLastTask()`, as this was causing a race\ncondition in the progress reporter tests. To retain legacy behavior, `.Write()`\nis now called explicitly after each update to the progress reporter throughout\nthe SalvusCompute codebase.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nchange_id = \"monotonic-filter-for-model-partitioning\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds a new `force_monotonic_top_down` function in\n`layered_meshing.layered_model.filters`. This is useful when the partitioning\nfield is known a-priori to be primarily monotonically increasing in the negative\nvertical direction, especially when slight variations in the model lead to local\ndeviations from monotonicity. Without applying this filter a naive\npartitioning may behave unexpectedly as variations in monotonicity can cause\nholes in simple predicates (i.e., those based on threshold velocity values)\nwhich will in turn prevent the partitioning algorithms from forming a clean\npartition.\n\nIt's usage for a simple acoustic model parametrized via velocites might look\nsomething like the following:\n\n```python\n\n...\n\npartition(\n  d=domain,\n  lm=layered_model,\n  model_predicate=filters.force_monotonic_top_down(lambda x: x.ds.VP),\n  mode=\"discontinuous\"\n)\n\n...\n\n```\n\nwhere the goal is to partition across a \"blurred\" sea bottom.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nchange_id = \"reduce-threshold-for-unstable-ict\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nReduces the threshold above which an inverse coordinate transform is allowed to\nbe unstable, from 1.05 to 1.0001 (in element reference coordinates). This change\nis driven by some instabilities encountered in a typical use case involving\nhigh-order topography and a deformed interface.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix job dependencies in the CI to avoid updating the API documentation prior\nto the tutorials on tagged pipelines.\\\n\"\"\"\n\n[[\"2024.1.3\".changes]]\nchange_id = \"packaging\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nReplace `distutils` by `packaging` when comparing version numbers and checking\nfor Salvus updates.\\\n\"\"\"\n\n\n[\"2024.1.2\"]\nrelease_date = \"2024-10-14\"\nrelease_message = \"\"\"\nThis is a minor release with several bug fixes and performance improvements.\n\nNew features include utilities for switching the material parameterization and\nextracting spatial gradients of a model, improved support for meshes stored in\nthe ExodusII file format, the ability to add new sites on the fly, a callback\noption for post-processing model updates in an inversion, and experimental\nsupport for importing sources on a fault using the Standard Rupture Format\n(SRF).\n\nThe performance improvements provide significant speed-ups for interpolating\nvolumetric models and local mesh refinements.\n\nFurther details are listed below.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nAdded a new method `get_waveform_data_xarray()` to `EventData` that enables the retrieval\nof waveform gathers as xarray.DataArray objects.\\\n\"\"\"\n\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nAdded HDF5DataProxy to parse HDF5 files and return an xarray.Dataset object.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nFix a bug caused by `multiprocessing` that would lead the mesh refinements to\nfail on OSX with Python>=3.8. The default start method for processes\non OSX was changed from `fork` to `spawn`\nwith Python 3.8 causing the mesh refinements to fail.\nAdd option to manually set the number of threads used for the mesh refinements\nvia an environment variable `SALVUS_MESH_REFINEMENT_NUM_PROCESSES`. If the\nnumber of threads is set to one, the mesh refinements will fully avoid\nusing multiprocessing (default on Windows).\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"model-gradient-extraction\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd functions to compute spatial derivatives of arbitrary fields\ndefined at the GLL points on an unstructured mesh using the\nLagrangian basis.\n\n```python\nimport sympy, numpy as np\n\nimport salvus.namespace as sn\nfrom salvus.mesh import layered_meshing as lm\n\nn = 4  # polynomial order\ndomain = sn.domain.dim2.BoxDomain(x0=0, x1=1, y0=0, y1=1)\n\n# Create a simple mesh to use as a test. Let parameters vary only in a\n# single direction so that we know their gradients in advance.\nmesh = lm.mesh_from_domain(\n    domain=domain,\n    model=lm.material.from_params(\n        vp=1 + sympy.symbols(\"x\"), rho=sympy.symbols(\"v\")\n    ),\n    mesh_resolution=sn.MeshResolution(\n        reference_frequency=10.0,\n        elements_per_wavelength=1.0,\n        model_order=n,\n    ),\n)\n\n# Compute the spatial derivatives of the model\nmesh.compute_spatial_gradients(fields=[\"VP\", \"RHO\"])\n\n# VP varies only in the x direction.\nnp.testing.assert_allclose(mesh.element_nodal_fields[\"dVP/dx\"], 1.0)\nnp.testing.assert_allclose(\n    mesh.element_nodal_fields[\"dVP/dy\"], 0.0, atol=1e-10\n)\n# RHO varies only in the y direction.\nnp.testing.assert_allclose(\n    mesh.element_nodal_fields[\"dRHO/dx\"], 0.0, atol=1e-10\n)\nnp.testing.assert_allclose(\n        mesh.element_nodal_fields[\"dRHO/dy\"],\n        1.0,\n    )\n```\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nBugfix attempt for sporadically failing CI by disabling most tqdm progressbars\nin the python tests.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"faster-interpolation-via-fast-interp\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nWhen interpolating xarray datasets using `get_interpolator(...)` from\n`xarray_tools`, faster interpolations are now provided via the fast_interp\npackage. This package will be used automatically if the interpolation source is\nregularly spaced, 2- or 3-D, and the \"linear\" interpolation method is selected.\nNote that if the source grid has a variable grid spacing in any one dimension\nscipy's regular grid interpolation routines will be fallen back on.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"bounding-box-search-for-local-refinement-policies\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds a new argument `enclosing_elements_method` to the `simple_post_refinements`\ngenerator. The default value is `\"inverse_coordinate_transform\"`, which retains\nlegacy behavior. Another value `\"bounding_box\"` is also supported, which trades\nthe accuracy of the enclosing element search to performance, as only a simple\nbounding box check is done to determine point ownership.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nNew `LocalRefinementPolicy`.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"bugfix-linear-solids-project-layered-mesher\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug where linear solids would not be properly passed to viscoelastic\ncartesian models in SalvusProject resulting in an error during mesh\ngeneration.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"bugfix-discrete-relative-models\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that erroneously tried to truncate discrete relative models when two\nneighboring interfaces had coincident reference elevations.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"bugfix-nonmonotonic-mesh\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the mesher where certain non-monotonic models would cause an error.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"do-not-decouple-child-processes\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvus on local sites typically fully decouples processes (e.g. running\ncomputations) from its parent process to allow for async workflows. In some\nsituations this is not desirable (e.g. one wants to ensure that all Salvus\nruns are terminated when the Python process is terminated). An optional\n`\"do_not_decouple_child_processes\"` flag for local sites has been introduced to\nsupport that behavior.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nRemoved .seis file reader and moved it to project phoenix.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nImprove the time stamp handling for task chains.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nAllow setting the `python_executable` to `sh run_python.sh` to allow for more\ncomplicated environment setups.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"on-demand-executor\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded the possibility to add new executors/sites on-the-fly, skipping all the\nchecks from the `salvus-cli init-site` step.\n\nUsage as a context manager is optional.\n\n```python\nwith sn.functions.add_new_executor(\n    site_name=\"my_other_site\",\n    executor_type=\"local\",\n    salvus_binary=salvus_binary,\n    run_directory=run_directory_2,\n    tmp_directory=tmp_directory_2,\n    use_cuda_capable_gpus=False,\n    default_ranks=1,\n    max_ranks=2,\n):\n    # Site is available here.\n    sn.functions.get_site(\"my_other_site\")\n  ```\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nA new `salvus._core.system` module yielding basic system information.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdded a new and temporary `_force_linear_shapes` parameter to the\n`MeshingProtocol` class to optionally skip the expensive high-order interface\nreinterpolation.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"read-exodus-files-with-multiple-blocks\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvus can now read Exodus files with multiple element blocks, read them\npartially and optionally store the element block index in the mesh.\n\n```python\n# To attach the block ids to the mesh\nm = sn.UnstructuredMesh.from_exodus(\n    filename, attach_element_block_indices=True\n)\n\n# To only read given blocks\nm = sn.UnstructuredMesh.from_exodus(\n    filename, select_element_block_indices=[2, 4],\n)\n```\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nUse the site-configured Python for the timing information in the task chain\nbash scripts.\n\nThis enables task-chains to run on systems without any `python` binary on the\n`$PATH`.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nGeneralized the `ReceiverBlock` and `SourceBlock` objects to support all\nreceiver and sources types.\n\nFurthermore added a `sn.Coordinates` object that can\nbe used to describe absolute or relative (to a side set, the top, or the bottom\nsurface of the mesh) coordinates.\n\n```python\nimport salvus.namespace as sn\n\n# Create 2 receivers with absolute cartesian coordinates.\nrb = sn.ReceiverBlock(\n    coordinates=sn.geometry.coordinates.Coordinates(\n        coordinates=[[0.0, 1.0], [1.0, 2.0]],\n    ),\n    fields=[\"displacement\"],\n    receiver_ids=[\"A\", \"B\"],\n)\n\n# Create 2 receivers, 1 and 2 meters below the top surface, respectively.\nrb = sn.ReceiverBlock(\n    coordinates=sn.geometry.coordinates.Coordinates(\n        coordinates=[[0.0, 1.0], [1.0, 2.0]],\n        reference=sn.geometry.coordinates.references.Depth(),\n    ),\n    fields=[\"displacement\"],\n    receiver_ids=[\"A\", \"B\"],\n)\n\n# Two scalar sources, one and two meters below the top surface in a spherical\n# system.\nsb = sn.SourceBlock(\n    source_mechanism=sn.source_mechanism.Scalar([0.0, 1.0]),\n    coordinates=sn.geometry.coordinates.Coordinates(\n        coordinates=[[0.0, 10.0, 1.0], [90.0, -50.0, 2.0]],\n        coordinate_system=sn.geometry.coordinates.CoordinateSystem.Spherical3D,\n        reference=sn.geometry.coordinates.references.Depth(),\n    ),\n)\n\n# Two vectorial side set sources.\nsb = sn.SourceBlock(\n    source_mechanism=sn.source_mechanism.Vector(\n        # Same mechanism for all sources! Can also be an array of mechanisms.\n        [0.0, 1.0]\n    ),\n    coordinates=sn.geometry.coordinates.Coordinates(\n        coordinates=[[0.0, 10.0], [0.0, 20.0]],\n        reference=sn.geometry.coordinates.references.Relative(\n            directions=[1.0, 1.0], side_set_name=\"surface\"\n        ),\n    ),\n)\n\neb = sn.EventBlock(source_blocks=[sb], receiver_blocks=[rb])\n# Get the corresponding Salvus event.\neb.get_event(event_name=\"event_a\")\n\n# Many events can be assembled into one big event block collection.\nebc = sn.EventBlockCollection(block_events=[eb], event_ids=[\"event_a\"])\n# Retrieve any event as a Salvus event.\nebc.get_event(\"event_a\")\n\np = sn.Project.from_domain(...)\n# The event block collection can be added to project which efficiently\n# serializes it to an HDF5 data set allowing projects with vast amounts\n# of sources and receivers.\np.events.add(ebc)\n```\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nAllow the use of external data proxies in distributed task chains.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\nchange_id = \"silence-paramiko-cryptography-warning\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFilter out the warning regarding cryptography's moved import, as with the\ncurrent environment as distributed, this doesn't affect Salvus users.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\nchange_id = \"bugfix-subsampled-receiver-misfit\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix for misfit computation when time axis is improperly subsampled. Happens\ni.e. when the last sample on a receiver (the last simulation time step) doesn't\nalign with regular time grid. This occurs when using a sampling interval\ngreater than one time step in the receiver output.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nFix missing plotting functionality of `_plot_wiggle` where one should be able\nto pass axes to plot into.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusMaterial\"\nchange_id = \"bugfix-oracle-attenuating-tensor-components\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix bug where attenuating tensor components are not split in base and visco\nparts when computing wavelengths.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nBugfix missing support for attenuation of Cij materials.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nChanged the definition of various transformations for acoustic hexagonal\nmaterials to align with the Mandel notation. Sped up the oracles for hexagonal\nacoustic materials by utilising the 2D eigenvalue problem.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nSpeed up MyPy by skipping two massive union types.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusMaterial\"\npublic_change = false\ndescription = \"\"\"\nSped up the oracles for ArrayParameter materials by removing unnecessary type\nchecks. Better retain realization information for oracles and related\nconversions.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdded better docstrings and \"force\" option for casting materials to\nincompatible material symmetries. Altered some (but not all!) transformations\nand oracles to retain realized parameter information via expand instead of\nstructure.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"mesh-material-conversions\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAllow conversion of unstructured mesh parameters using\n`mesh.transform_parameter`, which will automatically try to convert the\nparameters defined on a mesh to your chosen material, if they are compatible.\nReturns a new mesh. Ideal when a model in a different parametrization is\ndesired.\n\nWhen creating meshes from materials, typically the converted mesh will be\nidentical to a mesh generated from the converted material itself.\n\n```python\nimport salvus.namespace as sn\n\nfrom salvus import material\n\nd = sn.domain.dim2.BoxDomain(x0 =0, x1=10, y0=0,y1=10)\nmr = sn.MeshResolution(reference_frequency=1)\n\nmesh_material_iso = sn.layered_meshing.mesh_from_domain(\n    domain=d,\n    model=material.acoustic.Velocity.from_params(vp=1.0, rho=1.0),\n    mesh_resolution=mr,\n)\n\nmesh_material_tho = sn.layered_meshing.mesh_from_domain(\n    domain=d,\n    model=material.acoustic.elliptical_hexagonal.Velocity.from_params(\n        vpv=1.0, vph=1.0, rho=1.0\n    ),\n    mesh_resolution=mr,\n)\n\nconverted_mesh = mesh_material_iso.transform_material(\n    material.acoustic.elliptical_hexagonal.Velocity\n)\n\nassert converted_mesh == mesh_material_tho\n```\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nThe material module has been refactored:\n\n- Acoustic materials now use the same inheritance model as the elastic materials;\n- All common functionality between acoustic and elastic materials\n  has been raised to a higher level, leading to much less code. This removes\n  e.g. the ProvidesOracle interface and creates base materials and base tensor\n  component materials;\n- Better adherence to the import rules regarding relative imports;\n- No more concept of dimensionality for the material module.;\n- Brought typing up to Python 3.11 throughout module;\n- Refactor into public and private API.\n- Add ArrayParameter to consider non-spatial arrays of parameters.\n- Add UnassignedParameter.\n- Allow roundtripping of visco materials.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"thomsen-elastic\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAn elastic version of the Thomsen parameters material\n(`material.elastic.hexagonal.Thomsen`) is added, which has\n`from_acoustic` which needs injection of just 2 extra parameters.\nAdditionally, it can convert back using `to_acoustic`.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"srf-file-reader\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a reader for specifying seismic ruptures in the Standard Rupture Format\nVersion 2.0. This is useful for modeling a rupture along a fault by generating\na collection of point sources in Salvus.\n\nExample:\n```python\nfrom salvus.flow.simple_config.source.srf_file_reader import _read_srf_file\nfrom salvus.flow.simple_config.source.srf_to_salvus_sources import (\n    _create_sources_from_srf_data\n)\nsrf_data = _read_srf_file(\n    \"example.srf\",\n    plot=True,\n)\n# To generate the corresponding sources in a UTM domain:\nsalvus_sources = _create_sources_From_srf_data(\n    srf_data,\n    utm_crs,\n)\n```\n\nThis is an experimental feature and the API might change in the future.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nchange_id = \"callback-model-postprocessing\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a callback function to the Mapping class which allows to postprocess\nproposed model updates before validation of the misfit reduction. This feature\ncan be useful to introduce prior knowledge on material properties and to\nemphasize certain features in the model updates.\n\nExample:\n```python\ndef fixed_vp_vs_ratio(\n    proposed_model: sn.UnstructuredMesh,\n    prior_model: sn.UnstructuredMesh,\n) -> sn.UnstructuredMesh:\n    vp_vs_ratio = ... # some value\n    model_update = proposed_model.copy()\n    model_update.elemental_fields[\"VP\"] = vp_vs_ratio * model_update.elemental_fields[\"VS\"]\n\n    return model_update\n\nmapping = sn.Mapping(\n    inversion_parameters=[\"VS\"],\n    scaling=\"relative_deviation_from_prior\",\n    postprocess_model_update=fixed_vp_vs_ratio,\n)\n```\n\n`mapping` can then be passed to an `InverseProblemConfiguration` to enforce a\nfixed VP/VS ratio without inverting for VP.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"SalvusOpt\"\npublic_change = false\ndescription = \"\"\"\nFix a bug in serializing inversion models to disk. This would only\naffected inversion workflows with task chains.\\\n\"\"\"\n\n[[\"2024.1.2\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nEnable automated testing of the deploy pipeline for Project Phoenix.\\\n\"\"\"\n\n[\"2024.1.1\"]\nrelease_date = \"2024-07-02\"\nrelease_message = \"\"\"\nThis is the first minor update to the 2024.1 release.\n\nNotable changes include the handling of material parameterizations in Salvus\nand a new way of parallelism for simulations on shared filesystems (e.g. local\nsites or workstations). We have also made it a lot easier to add external data\nto a project.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"bugfix-ocean-depth\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug where the ocean layer would not be positioned correctly in cartesian\ndomains with strict top and bottom domain boundaries.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"fix-bug-in-bm-file-generation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe internal BM file writer in SalvusMesh previously did not check for invalid\ninterface definitions, and may have written BM files which contain a\ntriplication (or greater) of coordinate / value pairs at an interface. This has\nnow been remedied, and BM files generated via `get_bm_string` should now contain\nonly duplicated pairs at most. This issue may have affected those generating\nbackground models in SalvusProject from an n-dimensional xarray dataset.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix a bug in the anisotropic acoustic wavelength oracle that would return a\nnumpy oracle if passed an xarray material parameter.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nThe shared memory index file is now templated on hostname and username to\nallow usage on shared nodes and shared file systems.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"generic-from-params-and-dataset\"\nproduct = \"SalvusMaterial\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded generic `salvus.material.from_params()` and\n`salvus.material.from_dataset()` methods that will automatically find and\ninitialize the appropriate material class.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"updated-snippets\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nUpdated the Salvus Jupyter notebook snippets collection now works with Jupyter\nnotebooks >= 7 as well as JupyterLab.\n\n```python\n%load_ext salvus\n%salvus_snippets\n```\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"custom-data-normalization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvus now supports custom data normalization functions for use in misfit\ncomputations and inverse problems.\n\n```python\n    def forward_norm(data_synthetic, data_observed, sampling_rate_in_hertz):\n        ...\n\n    def jacobian_norm(\n        adjoint_source, data_synthetic, data_observed, sampling_rate_in_hertz\n    ):\n        ...\n\n    norm = sn.TraceNormalization(forward=forward_norm, jacobian=jacobian_norm)\n    p += sn.MisfitConfiguration(\n        ...,\n        normalization=norm,\n    )\n```\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"add-external-data\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded new functionality to facilitate adding external data\nto a Salvus project per event. The function\n`salvus.data.external_data_to_hdf5` takes an\n`xarray.Dataset`, validates it, and converts it to a Salvus\ncompatible HDF5 file, which can be added to a project.\n\n```python\n\nfrom salvus.data import external_data_to_hdf5\nfor event in project.events.list():\n  external_data_to_hdf5(\n    data=data_per_event,\n    receivers=event.receivers,\n    receiver_field=\"displacement\",\n    output_filename=external_data_path,\n  )\n  project.waveforms.add_external(\n        data_name=\"observed_data\",\n        event=event.event_name,\n        data_filename=external_data_path,\n  )\n\n```\\\n\"\"\"\n\n\n[[\"2024.1.1\".changes]]\nchange_id = \"salvus-material-top-level-module\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe material submodule of the layered_mesher has been promoted to a\nfull-fledged top level module for Salvus. Although it is still available as an\nalias in the layered mesher submodule of salvus.mesh (i.e.\n`salvus.mesh.layered_mesher.material`), accessing it this way is not\nencouraged.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"materials-background\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded the option to pass materials to background models, per the following\nmethod:\n\n```python\n# Acoustic isotropic material\nmaterial_sandstone = material.acoustic.Velocity.from_params(\n    rho=1500, vp=1875\n)\n\n# Or something more exotic\nmaterial_weird_sandstone = material.elastic.triclinic.TensorComponents(\n    ...\n)\n\nmc_sandstone = sn.ModelConfiguration(\n    background_model=sn.model.background.homogeneous.FromMaterial(\n        material=material_sandstone\n    )\n)\n\nsc_sandstone = sn.SimulationConfiguration(\n    name=\"sandstone\",\n    model_configuration=mc_sandstone,\n    ...\n)\n```\nOnly supports homogeneous and not location-dependent materials.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nSerialization of constant materials and bugfixes for integers passed to\nmaterials.\\\n\"\"\"\n\n\n[[\"2024.1.1\".changes]]\nchange_id = \"misfit-widget-event\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded optional `events` as a setting to `p.viz.nb`'s `misfits`, to visualize\nmisfits only for selected events. If not passed, to previous default of all\nevents will be used. Also allows silent query for `p.simulations.query()`,\nuseful when calling query often and keeping output down.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"fast-unsafe-gather\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded `fast_unsafe` as a setting to `p.viz.nb`'s `shotgather` and\n`custom_gather`, to visualize data not on the most dense but on the most sparse\ntime axis of the selected datasets. This might alias data.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"enclosing-side-sets\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded `find_side_sets_enclosing` as a method to meshes to find a all side sets\nthat enclose the mesh, by first finding all planar surfaces and constructing\nthe remainder surface from all unclaimed facets.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nSmall changes from working on Innosuisse:\n- Syntax error in old changelog entry;\n- Added more text to a docstring in `notebook_visualization_component`;\n- More verbose mounts for the devcontainer.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nFix bug that occurs when attempting to add external data with the receiver_ids\narray being larger than 64kb.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"subsampling-misfits-fix\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug when computing misfits would not honor\n`receiver_sampling_rate_in_time_steps` of a simulation configuration. By\ndefault, Salvus will now drop the final data point if it does not lie on the\nregular time grid of the subsampled simulation output, e.g. with 100 time\nsteps, but with a receiver sampling interval of 11. These are the sampling\nrates that can be set via:\n```\nsn.WaveformSimulationConfiguration(\n    receiver_sampling_rate_in_time_steps=11, ...\n)\n```\nTo recreate the previous behavior, use\n`EventData.get_waveform_data(..., enforce_regular_time_grid=False)`, but note\nthat the resulting data will only be regularly spaced for all but the last\nsample.\n\nEventData's `get_time_axis_from_meta_json` now optionally allows passing which\noutput type the time axis needs to be retrieved for, defaulting to the\nsimulation's time axis (no subsampling).\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"fix-error-reporting-for-extra-output-configuration\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove the error reporting for re-running simulations in SalvusProject with\nmodified outputs in the `extra_output_configuration`.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix integer type casting in SeisIO reader.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd pipeline for automatically deploying the project phoenix release to ftp.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"fail-on-wrong-project-path\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove the error message when trying to load a project from a path that either\ndoes not exist or is not a directory.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"taskchains-for-simulations\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvus now supports a new way of launching simulations using\n`p.simulations.run()`. This function waits for all simulations to finish before\nreturning and enables a new way of parallelism.\n\nIn addition to specifying the site configuration with `sn.SiteConfig`, this new\nfunction can also run several simulations in parallel on a local (or ssh)\nsystem, which can give a substantial speed up for use cases with many small\nsimulations.\n\nUsage example:\n```python\n    task_chain_config = TaskChainSiteConfig(\n        site_name=\"test_site\",\n        number_of_parallel_workers=5,\n        ranks_per_salvus_simulation=2,\n        max_threads_per_worker=2,\n        shared_file_system=True,\n    )\n\n    p.simulations.run(\n        events=p.events.list(),\n        simulation_configuration=\"my_simulation\",\n        site_config=task_chain_config,\n    )\n```\nThe feature is currently still experimental. Additional output settings are not\nyet supported and we recommend using `p.simulations.launch()` for those\ninstead.\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nchange_id = \"speed-up-input-file-generation-and-hashing\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSpeed up the generation of input files and hashes of simulations.\nThis should give a noticeable improvement for simulations with event-dependent\nsources and many events.\n\nIn addition, a utility to simultaneously query the output directories for\nseveral events has been added:\n\n```python\np.simulations.get_simulation_output_directories(\n    simulation_configuration=\"my_simulation\",\n    events=p.events.list()\n)\n```\\\n\"\"\"\n\n[[\"2024.1.1\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nBug fix for inversion workflows with task chains. For testing purposes, task\nchains are now also enabled for inversions. However, not all processing\nfeatures are supported yet, which is why it is not a public change yet.\\\n\"\"\"\n\n[\"2024.1.0\"]\nrelease_date = \"2024-05-15\"\nrelease_message = \"\"\"\nThis is a major release which brings in several important changes. **Salvus now\nnatively supports Windows**, which required a lot of modernizations and changes\nunder the hood. However, we've been able to largely maintain backwards\ncompatility with the existing API.\n\nSee [here](https://docs.mondaic.com/installation/platform_specific/windows)\nfor the installation instructions.\n\nFurther notable changes include:\n\n- The dependency to `libmpicxx` has been removed. Salvus runs with any\nABI-compatible MPI implementation such as MPICH and only the C-interface and\nlibrary is required at runtime.\n- A versioning scheme for organizing a project's internal files has been\nintroduced.\n- A major upgrade of the internal meshing routines for layered models and an\noverhaul of the implementation of linear solids.\n\nAdditional new features and bug fixes are listed below.\n\nIf you have any questions or concerns about upgrading, please reach out in the\n[user forum](https://forum.mondaic.com) or contact support@mondaic.com .\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nStreamline naming conventions and doc strings.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nUnify the interface of the mesh generators.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate to nanoflann 1.5.3, mpich 3.4.3, and curl 8.4.0.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate black version target to py311.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nReorganize cubed sphere functionality for MEP-102.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nFix querying the status of a running process on OSX and Linux.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nchange_id = \"salvus-cli-status\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in `salvus-cli status` that would throw an index error when trying\nto query empty job arrays from the database.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nchange_id = \"rework-linear-solids\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nAdd utilities for converting attenuation parameters and unify the handling of\nlinear solids.\nThe class `sn.simple_mesh.linear_solid.LinearSolid` has been removed and\nsuperseded. The class `sn.LinearSolids` can be used directly for a constant Q\napproximation. Alternatively, and for more fine-grained control, the\ncoefficients of the standard linear solids (SLS) can be obtained using\n`salvus.material.attenuation.lsqr_fit_q_factor_model`.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nchange_id = \"upgrade-petsc-and-mpi\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nUpgrade to PETSc 3.20.5 and remove dependency on `libmpicxx`.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nchange_id = \"adjoint-sources-for-receiver-channels\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdjoint sources can now be computed for receiver channels.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nExperimental visualization of project dependencies with graphs.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\nchange_id = \"side-set-algorithms-for-delamination\"\ndescription = \"\"\"\nAddition of algorithms to modify side sets in\n`salvus.mesh.algorithms.unstructured_mesh_utils`: `retain_unique_facets`,\n`uniquefy_side_sets`, `get_internal_side_set_facets`,\n`disconnect_along_side_set`.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nchange_id = \"utility-misfit-getter\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd methods to get all misfits of inversion and method to get all\ninverse_problem_configurations, respectively `p.inversions.get_misfits()`\nand `p.entities.get_inverse_problem_configurations()`.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nExperimental implementation of HDF5 compression for wavefield output and\nmeshes.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nchange_id = \"surfaces-and-rotation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAllow one to compute normal vectors and related rotation matrices for side sets\nof a mesh.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd ccache (cached compilation) and go back to a root mamba installation.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nClosing unclosed files.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nCleanup for Salvus 2024.1.0.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nTowards a proper module hierarchy.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nBeta release of Salvus on Windows.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nC++ and Python unit tests in the Windows CI.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nCross-platform SharedMemoryUnstructuredMesh class.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nBreak up the unstructured mesh class.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nchange_id = \"updated-snippets\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nUpdated the Salvus Jupyter notebook snippets collection. It can be\naccessed by executing the following in a Jupyter notebook:\n\n```python\n%load_ext salvus\n%salvus_snippets\n```\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nchange_id = \"catch-obpsy-warnings\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe default seismology data processing function shows a lot of warnings of the\nexternal library `ObsPy`. If the `wurlitzer` library is installed, it will now\nbe used to suppress these warnings.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nchange_id = \"salvus-project-versioning\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nStart versioning the file structure of SalvusProject. User are able to migrate\nfrom an older version of the file structure to a newer one.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd default GPU architecture for clangd.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nNumPy point sorting.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nFix uninitialized memory in SalvusPhysics anisotropic acoustic test.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAttempt to fix potential race condition in progress reporter tests on Windows.\\\n\"\"\"\n\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for high-order reinterpolation in spherical domains.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix potential segfault in max / min mesh coordinate reduction.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nLayered meshing backend for spherical domains.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd basic infrastructure for general numpy / c++ Python bindings via mdspan.\\\n\"\"\"\n\n[[\"2024.1.0\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nClean up some refinement templates.\\\n\"\"\"\n\n[\"0.12.16\"]\nrelease_date = \"2024-02-26\"\nrelease_message = \"\"\"\nThis is a minor release with several quality of life improvements and minor bug\nfixes as listed below. New features include receiver channels for modeling\nultrasonic sensors, better handling of volume and surface data, transformations\nfor moment-tensor sources in UTM domains, and utilities to preprocess layered\nmodels.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"adding-utm-source-transformations\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded spherical to UTM moment tensor transformations, both ways.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"receiver-channel-integration\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded the option to combine data from several receivers into\na single output channel. Each channel is a weighted sum\nof the individual, potentially time shifted, receiver signals.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"bugfixes-inversion-adding-new-events\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nBugfixes and utility functions that simplify adding new events to ongoing\ninversions. Demonstrated in\n[this tutorial](https://docs.mondaic.com/examples/applications/seismology/continental_scale_fwi/04_iterative_inversion).\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nAdd (de)convolution functionality to block processing.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd Cijkl materials to the layered mesher.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nUpdate the tqdm usage and language in the chunked mesher.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd the ability to natively extrude meshes so that they contain sponge layers\nfor 2- and 3-D spherical domains.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd the ability to compute ellipticity in layered models, and fixed a bug that\ncould drastically over-estimate the number of elements required for 3D fully\nspherical meshes.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nReplace the acoustic 2-d spherical basic mesh constructor and the circular mesh\ngeneration in project to use the LM. For consistency with the other layered\nmeshing algorithms, meshes created via these methods will no longer contain the\n`\"discontinuities\"` or `\"z_centroid_1D\"`.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd the ability to mesh oceans in spherical chunk / full sphere domains within\nthe layered mesher. Fix a typo in the mesh widget.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for specification of spherical shells and full spheres in the layered\nmesher, along with 3-D spherical models and topography.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for rotated spherical chunks in the layered mesher.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"some-model-utilities\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThis change brings in three utilities for working with layered models. In\nparticular, they are:\n\n- `split_layered_model`: This function allows for a layered model to be split\n  into two based on conditions targeting the model's interfaces or materials.\n- `flood`: This function allows for a layer's material parameters to be\n\"flooded\", or extruded, in the vertical direction.\n- `blend`: This function supports the blending of two materials, and currently\nsupports the averaging of constant parameters, as well as the linear or\ncosine-taper-based blending of discrete models along their vertical coordinate.\n\nAdditional details and documentation can be found along with the functions\nthemselves in the `salvus.mesh.layered_meshing.utils` module.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nCompatibility with joblib >= 1.3.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nThe devcontainer now uses a user installed mamba.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nIgnore the __all__ variable for the doc generation/linting.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nRemove future warning for pandas 3.0 and scipy 1.14.0.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"track-extra-output\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvusProject now tracks the `extra_output_configuration` argument passed\nto `p.simulations.launch()`. It will detect if the simulations have\npreviously been run with different output settings and will optionally\noverwrite existing results.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"improved-retry-decorator\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove error messages in case retried operations fails.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"improved-wavefield-output-handling\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nBetter surface and volume output handling by the EventData object for advanced\nusage patterns Salvus:\n\n* New `EventData.get_wavefield_output()` method parsing outputs to\n  `WavefieldOutput` objects.\n* New `EventData.get_associated_salvus_job()` method returning a potentially\n  still existing Salvus job for the `EventData` object.\n* New `EventData.get_remote_extra_output_filenames()` method to get paths of\n  remote output files.\n* New `EventData.download_extra_outputs()` method to download remote wavefield\n  output data.\n* New `EventData.delete_associated_job_and_data()` method to delete potentially\n  still existing remote wavefield data.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate to black 24.1.0.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"update-python-dependencies\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd support for `numpy>=1.26.0` and `xarray>=2023.10`.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSecurity audit for SAST compliance with bandit 1.7.6.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate copyright headers to 2024.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nImprove robustness of gradient integration tests.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"fix-auto-times-in-simple-config\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in computing the suggested start and end times of analytic source\nwavelets (e.g. Ricker, GaussianRate) with time shifts.\nPreviously, when specifying custom time shifts to analytic wavelets, the time\nshifts where not reflected in the auxiliary functions to plot the wavelet.\nThis did not affect the actual start and end times used in the simulation.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"fix-window-picking-time-axis\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a check in the window picking algorithm to ensure the time axis of the\nobserved data is consistent with the synthetics. Traces for which the observed\ndata do not cover the entire simulated time interval will be ignored during\nwindow picking, and the stations will be written to a log file.\n\nSuch situations previously raised a `ValueError` which was hard to recover\nwithout manually removing the delinquent stations from the observed data.\\\n\"\"\"\n\n[[\"0.12.16\".changes]]\nchange_id = \"fix-misfit-comparison-table-duplicates\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in `get_misfit_comparison_table()`, which would trigger an exception\nwhen passing the same data for comparison multiple times.\\\n\"\"\"\n\n[\"0.12.15\"]\nrelease_date = \"2023-11-26\"\nrelease_message = \"\"\"\nThis is a minor release with several quality of life improvements and minor bug\nfixes as listed below. New features include the ability to customize shotgather\nplots and enabling the static output of the wavefield at final time.\n\nThis is the first release that supports Python 3.11.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nchange_id = \"allow-verbosity-project\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded verbosity parameter to all methods creating a Salvus Project.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdded the Git Graph extension to the dev container.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nchange_id = \"adding-custom-gather-plots\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nAdded custom gather plots to Salvus Project, which allows one to sort, filter,\nor use self defined operations on receivers, to collectively plot multiple\nevents and datasets to plots them. Note that this also changes the signature of\nthe existing `shotgather`; it will no longer accept width, height and DPI, but\ninstead accepts a dataclass with those fields, or an existing axes, passed as\n`plot_using`.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix issue with incorrect partial read of global topography files in azimuthally\nrotated domains.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for specification of spherical shells and full spheres in the layered\nmesher, along with 3-D spherical models and topography.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate devcontainer configuration to allow for easier setup and multiple python\nversions.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nUpdate the layered mesher to properly handle oceans in Cartesian domains, as\nwell as add many member functions to the `LayeredModel` class. To enable these\nchanges, the vertical coordinates of discrete parameters can now be\nparameterized relative to their corresponding layer's vertical extent. To enable\nrelative parameters, a new experimental and vectorized implementation of the\ninverse coordinate transform and elemental interpolation routines has also been\nadded for performance reasons.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nInitial set of changes to get the Python code running on Windows.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSupport for mypy >= 1.5.0 on Python 3.9-3.11. No longer supports mypy <1.5.0.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSupport for compiling the Python wheel with Cython 3.0.5.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nchange_id = \"job-array-cancelling-fix\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix issue with how cancelled job arrays are represented in the internal job\ndatabase.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSupport for compiling on arm64.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSupport the devcontainer on arm64.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nchange_id = \"compatibility-with-xyzservices-2023-10-1\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSupport for xyzservices >= 2023.10.1 as well as unifying Salvus' approach to\nweb basemaps.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\n`salvus-cli upgrade-site` now correctly detects the version of the Salvus\nPython wheel on the remote site.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nchange_id = \"domain-estimate-travel-distance\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new `compute_max_distance_in_m()` function that computes the maximum\ndistance between any two points in a given set in Cartesian or spherical\ncoordinates.\n\nAdditionally a new `.estimate_max_travel_distance_in_m()` method is available\nfor all domain object utilizing the new function. This is useful for example to\njudge the approximate time waves will take to travel through a given domain.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nchange_id = \"fix-mesh-widget\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a problem with the notebook mesh widget. It now properly display meshes\nwith few and thin elements in 2-D and 3-D.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nFix a spurious error that sometimes occured when testing warnings in the\nMisfitConfiguration.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpgrade dependencies in SalvusExternal and add the ability to compile with\npy311.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix a spurious error in testing project workflows for cancelling jobs.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nchange_id = \"final-time-output\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the ability to output the final state of a simulation. Using a new output\nkey `final_time_data` it is possible to output the primary fields\n(`displacement`, `velocity`, `phi`, `phi_t`) at final time on an unstructured\nmesh. The output file will thus be independent from the partition and number of\nranks used in the simulation.\n\nExample as part of the `extra_output_configuration` in `p.simulations.launch`:\n\n```python\n    extra_output_configuration={\n        \"final_time_data\": {\"fields\": [\"displacement\"]},\n    },\n\n```\n\nor directly in the `simple_config` simulation object:\n\n```python\n    w.output.final_time_data.format = \"hdf5-minimal\"\n    w.output.final_time_data.fields = [\"displacement\"]\n    w.output.final_time_data.filename = \"final_time.h5\"\n```\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix a bug in handling Euler angles for processing topography data.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd support for mypy>=1.7.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpgrade type validation tests and add missing python tests to CI.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nEnable the use of external data files for testing via pooch.\\\n\"\"\"\n\n[[\"0.12.15\".changes]]\nchange_id = \"increase-max-default-ranks\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable site configurations with a high number of default ranks. This was\npreviously limited to 100. While we still recommend using a small number here,\nit is now possible to go up to 1024 ranks.\\\n\"\"\"\n\n[\"0.12.14\"]\nrelease_date = \"2023-09-11\"\nrelease_message = \"\"\"\nThis is a minor release with small improvements listed below. Additionally,\nthe documentation of the Python API has been improved.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for the specification of full circles in the layered mesher.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for the ingestion of `POLY`-style BM files in the layered mesher.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd a release pipeline stage to test the pyforge repo.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nchange_id = \"option-for-custom-axes-in-receiver-plotting\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the option to plot the coordinates of an `EventBlockData` object in a\ncustom axes frame.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix a bug that caused many functions not to be documented.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nType hints are mandatory for all functions now and all docstrings are linted.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix job access tokens for release pipelines.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpgrade to fastjsonschema >= 2.18.0.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nUpdate built-in upgrade instructions.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nchange_id = \"custom-fields-in-mesh2mesh\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the ability to interpolate custom fields when performing mesh-to-mesh\ninterpolation:\n\n```python\nfrom salvus.mesh.tools.transforms import interpolate_mesh_to_mesh\n\nint_mesh = interpolate_mesh_to_mesh(\n    ...,\n    fields_to_interpolate=[\"custom\"],\n)\n```\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nchange_id = \"compatibility-with-pandas-210\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnsure compatibility with `pandas>=2.1.0`.\\\n\"\"\"\n\n[[\"0.12.14\".changes]]\nchange_id = \"bug-fix-parse-event-from-asdf\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in parsing events from ASDF files, which caused a `ValueError` in\nsome cases when adding events through `p.actions.seismology.add_asdf_file()`.\\\n\"\"\"\n\n\n[\"0.12.13\"]\nrelease_date = \"2023-07-04\"\nrelease_message = \"\"\"\nThis is a minor release with a few bug fixes listed below.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nTemporary workaround for bug in UTM oceans.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nFix an unused type-ignore statement in the dim3.UtmDomain.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow, in the layered mesher, for specifying top layers that can have a thickness\nthat is less than or equal to 0. This is useful for modelling ocean layers in\nboth Cartesian and spherical domains, and brings with it the ability to use\nadditional refinement templates for the `IntralayerVerticalRefine()` policy.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for basic circular shell meshes within the layered mesher public API.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for simple meshes with analytic parameters in the layered mesher public\nAPI.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nVarious documentation improvements.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nThe yes/no question for GPUs in the `salvus-cli add-site` wizard now requires\na return if a user changed the default value.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"SalvusUtils\"\npublic_change = false\ndescription = \"\"\"\nAdd a native hash for pathlib.Path objects.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd regression tests for circular and spherical basic meshes.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nAdd back regression tests for hashes in SalvusProject.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nchange_id = \"fix-material-in-exterior-domains\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nWhen building meshes with exterior domains for modeling the gravitational\npotential, all material parameters will automatically be set to zero.\nFurthermore, the exterior is assigned a unique `layer` id, which increments\nthe layer id at the surface by one.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nchange_id = \"fix-bug-get-misfit-table\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the visualization widget of an inverse problem, which could cause\na `ZeroDivisionError` if there were one or more events without windows in the\ndata selection.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFilter deprecation warnings for importing windows directly from\n`scipy.signal`.\\\n\"\"\"\n\n[[\"0.12.13\".changes]]\nchange_id = \"fix-window-picking-bug\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the window picking algorithm which caused a `TypeError` for\nconstant traces.\\\n\"\"\"\n\n[\"0.12.12\"]\nrelease_date = \"2023-05-31\"\nrelease_message = \"\"\"\nThis release brings in a new backend of the Cartesian meshing algorithms.\nThose changes do not affect the API. In some scenarios, the resulting mesh\ncan change slightly, because of the improved meshing algorithms. If you\nnotice undesired changes, please reach out in the user forum or message\nsupport@mondaic.com\n\nThis is also the first Salvus release that supports Python 3.9. You can choose\nthe Python version from the interactive menu in the downloader.\nMore information can be found [here](https://docs.mondaic.com/updates)\nNote that Python 3.7 will reach its end-of-life at the end of June 2023.\\\n\"\"\"\n\n[[\"0.12.12\".changes]]\nchange_id = \"salvus-cli-upgrade\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `salvus-cli upgrade` command now works in cases where the upgrade changes\nthe initialization logic of Salvus.\\\n\"\"\"\n\n[[\"0.12.12\".changes]]\nchange_id = \"error-for-nonzero-min-depth\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nBM files parameterized using depth now explicitly need a model value specified\nat depth = 0. This is to avoid ambiguities that could otherwise occur in the\nvertical span of the mesh.\\\n\"\"\"\n\n[[\"0.12.12\".changes]]\nchange_id = \"upgrade-meshing-backends\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe backend Cartesian meshing algorithms have been improved, and this may result\nin changes to some meshes. If you notice significant undesired changes, or\nencounter and other problems, please contact us.\\\n\"\"\"\n\n[[\"0.12.12\".changes]]\nchange_id = \"deprecated-chunked-meshing\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nThe `salvus.mesh.chunked_interface.create_mesh_chunkwise()` function is now\ndeprecated.\\\n\"\"\"\n\n[[\"0.12.12\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nBuild and deploy python wheels for 3.9.\\\n\"\"\"\n\n[\"0.12.11\"]\nrelease_date = \"2023-05-09\"\nrelease_message = \"\"\"\nMinor release with a few bug fixes and other small improvements listed below.\n\nHighlights of new features include the ability to output volumes and surfaces\non a subinterval of the simulation time axis, improved functionality to\nextrude meshes and an experimental feature to invert for the source wavelet.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix some bugs where there layered mesher would fail if a layer was thinner\nthan the extent of its elevation model.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd a `setup_dev_site.sh` script in `conf` that allows for the easy creation of\na site within the devcontainer.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"time-brackets\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds the ability to output surface and volume fields only between certain times.\nTo access this functionality, the `start_time_in_seconds` and\n`end_time_in_seconds` can now be passed to the respective output groups\nin a `simulation.Waveform(...)` object. Times passed are always truncated\n(floored) to the preceding time step.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"new-batched-algorithm-for-wavefield-output\"\nproduct = \"SalvusUtils\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new algorithm that groups elements by their number of occurrences before\nperforming the wavefield output tensor contraction. This should be close to the\nmost efficient approach in all cases, so it is also now the default when\nextracting a `WavefieldOutput` object to an `xarray`.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"center-spherical-chunks\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe mesh notebook widget will now initialize its camera to point at the center\nof spherical chunks.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix a few security issues discovered with the latest bandit release.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"ipywidgets8\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdding support for ipywidgets8.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"consider-origin-time-in-window-picking\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nThe window picking algorithm for seismology now correctly handles cases where\nthe event origin time is not the time of the first sample of the synthetics.\n\nA consequence of this is that custom window picking functions must now also\nhave a `event_origin_time` keyword argument. We believe this should not affect\nany users, if it does: the error message is very clear and fixing it is\nstraight forward.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"extrude-higher-order-meshes\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nHigher-order meshes can now be extruded from 2-D to 3-D.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"extrude-material-parameters\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nMaterial parameters will now also be extruded when meshes are being extruded.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nWe now use numpy's type hints + the numpy mypy plugin, as well as pyproj's\ntype hints.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSupport for the latest versions of all dependencies from Python 3.7 to Python\n3.10.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"dicts-as-sources-and-receivers\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a regression where sources and receivers could not longer be specified as\ndictionaries.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdded a few regression tests for the basic mesh constructors including the\nabsorbing boundaries.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"enforce-unique-boundary-types\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnforce that each type of boundary condition can only be added once to a\nsimulation object to ensure that the boundary conditions are treated\nproperly in SalvusCompute.\n\n```python\nw = sn.simple_config.simulation.Waveform(mesh=m)\n\n# If all settings for the same type of boundary condition are the same,\n# the side sets will be merged.\nw.add_boundary_conditions([\n  sn.simple_config.boundary.HomogeneousDirichlet(side_sets=[\"x0\"]),\n  sn.simple_config.boundary.HomogeneousDirichlet(side_sets=[\"x1\"])\n])\n\n# However, using different settings for a boundary type will raise an error.\nw.add_boundary_conditions([\n  sn.simple_config.boundary.Absorbing(\n    side_sets=[\"x0\"], taper_amplitude=0.0, width_in_meters=0.0\n  )\n  sn.simple_config.boundary.Absorbing(\n    side_sets=[\"x1\"], taper_amplitude=1.0, width_in_meters=1.0\n  )\n])\n```\n\nThis is now part of the validation of the simple config objects.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nEnable explicitly enabling private functions to appear in the public API\ndocumentation.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUse job and project access tokens instead of the SalvusBot user.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpgrade to mypy 1.2.0.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd ability to deploy custom binaries from the CI.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"fix-license-token-release-adjoint\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that could cause a failing license request when using tokens in\nadjoint simulations.\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"fix-gradients-in-fully-anisotropic-3d-media\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in computing gradients with respect to the C_ij components of the\nelastic tensor in fully anisotropic 3D media..\\\n\"\"\"\n\n[[\"0.12.11\".changes]]\nchange_id = \"source-inversion-single-component-acoustic\"\nproduct = \"SalvusModules\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds the ability to invert for source characteristics for single-component\n(acoustic) data.  There are currently two interfaces for performing such a\nsource inversion in the `salvus.modules.source_inversion` submodule by using\none of the following functions:\n- `invert_wavelet`: Accepts the observed and synthetically generated data as\nNumPy arrays and returns the inverted wavelet as a NumPy array.\n- `invert_wavelet_from_event_data`: Performs the same inversion as within\n`invert_wavelet`, but accepts `EventData` objects instead of NumPy arrays.\nThis is generally the more convenient approach when used together with\nSalvusProject.\n\nNote that inverting for multi-component data is currently unsupported.\\\n\"\"\"\n\n[\"0.12.10\"]\nrelease_date = \"2023-03-15\"\nrelease_message = \"\"\"\nFirst release of 2023 with several small improvements in various components\nof Salvus. Details are listed below.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"error-messages-unsupported-receivers\"\nproduct = \"SalvusModules\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThrow a descriptive error message when trying to use the waveform database\nwith unsupported receiver types.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate copyright headers to 2023 in all source files.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate to black 23.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"fix-handling-location-codes-in-asdf\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd support ASDF output for receivers that only differ by location code.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"add-customizable-function-for-gardners-relation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd function to compute the density model based on Gardner's relation,\nand support customizable Gardner's constants alpha and beta.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"enable-fft-on-subinterval\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable passing start and end time for computing the discrete Fourier\ntransform as extra output configuration in SalvusProject.\n\nExample:\n```python\np.simulations.launch(\n    simulation_configuration=\"my_simulation\",\n    events=p.events.list(),\n    ranks_per_job=2,\n    site_name=\"local\",\n    extra_output_configuration={\n        \"frequency_domain\": {\n            \"frequencies\": [10.0],\n            \"fields\": [\"phi\"],\n            \"start_time_in_seconds\": 1.0,\n            \"end_time_in_seconds\": 1.1,\n        }\n    }\n)\n```\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"enable-events-without-receivers\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that would prevent launching simulations of events without receivers\nin SalvusProject. This can be useful, for instance, if only volumetric output\nis desired.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"slurm-custom-commands\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThere is a a new `custom_commands` setting for Slurm sites to add custom\nbash commands to a job script.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate to mypy 1.0.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdapting to a change in matplotlib.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"logging-helpers\"\nproduct = \"SalvusUtils\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new `salvus.utils.logging.log_timing()` context manager that logs the\ntime the context takes to execute.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"receiver-weighting-few-windows\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nStability improvements in the receiver weighting algorithms in case a\nparticular event has no or very little windows.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"reinterpolate-side-sets\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds a new function `mesh.adjust_side_sets.adjust_site_set` that allows for the\nre-interpolation of a mesh's vertical side set to a new digital elevation model,\npotentially at a higher order than originally used. This can be useful, for\ninstance, when changing frequency bands and taking advantage of the smaller mesh\nsize to better resolve topography, changing a mesh's model order, or\nre-interpolating after adding local refinements. This re-interpolation also now\nhappens by default when using the layered meshing interface.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for the simple generation of oracle filters and local refinement policies\nfor the common case where one wants to a) clip the wavelength oracle so that\nsmall wavelengths are ignored in the first pass, and b) refine those clipped\nareas using local refinements after the initial mesh generation stage.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix a bug where the layered mesher may not double between layers where the\nvelocity does not jump.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix a bug where the objective function for the interlayer coarsening algorithm\nwas not stated correctly for 3-D meshes.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"python-interface-for-3d-surface-output\"\nproduct = \"SalvusUtils\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds the ability to properly handle surface output in the\n`salvus.toolbox.helpers.wavefield_output` module. To use this, one simply needs\nto pass \"surface\" as an output type when loading the wavefield output. Also\nadded the ability to drop dimensions from outputs, so 3-D surface outputs can be\nvisualized in 2-D planar plots (such as in matplotlib). This can be accessed by\ncalling the `.drop(...)` function on a `WavefieldOutput` instance.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nUnify the implementation of the interlayer connector protocols, fix the\nimplementation for reversed connectors in 3-D, and finish the tripling\nimplementation. Also add some new utility functions, including the ability to\ncompute the jacobian efficiently for large meshes.\\\n\"\"\"\n\n[[\"0.12.10\".changes]]\nchange_id = \"velocity-parameterization-for-anisotropic-acoustic-models\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nBoth 2- and 3-d anisotropic acoustic models can now be specified in terms of\nvelocities (rho, vph, and vpv). Note that this parameterization implies that\nepsilon = delta.\\\n\"\"\"\n\n[\"0.12.9\"]\nrelease_date = \"2022-12-22\"\nrelease_message = \"\"\"\nThis is a minor release that fixes a few bugs as well as adds some new\nfeatures. Most notable of these new features are a) an improvement to\nSalvusCompute's time-step computation algorithm which now takes into account\nthe influence of any absorbing boundary layers, which may improve the stability\nof some simulations, and b) a new set of functionality to interpolate\ntime-dependent volumetric wavefield data onto a set of arbitrary points,\nincluding regular grids, for the purpose of simplyfing the analysis of such\ndata.\\\n\"\"\"\n\n[[\"0.12.9\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for setting the maximum aspect ratio in `IntralayerVerticalRefine(...)`\npolicies. An aspect ratio of x means that the element size in the vertical\ndirection is no more than x times the element size in the horizontal direction.\\\n\"\"\"\n\n[[\"0.12.9\".changes]]\nchange_id = \"wavefield-output-to-points\"\nproduct = \"SalvusUtils\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds new functionality in `salvus.toolbox.helpers.wavefield_output` to help\nencapsulate and manipulate raw volumetric wavefield output from SalvusCompute.\nAdditional functions allows for the extraction of time-dependent wavefield data\nfrom said files to regular grids in space and time.\\\n\"\"\"\n\n[[\"0.12.9\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for deformed size functions in the IntralayerVariable policy. One can now\npass `allow_deformed_size_function=True` to the policy. Also: fix intralayer\nvariable coarsening policy, so as to properly consider the maximum number of\nwavelengths along a vertical edge in a dimension, rather than the minimum! Added\na test to this effect.\\\n\"\"\"\n\n[[\"0.12.9\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nInitial implementation of an IntralayerVariable coarsening policy.\\\n\"\"\"\n\n[[\"0.12.9\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for viscoelasticity as an optional parameter in the layered mesher.\\\n\"\"\"\n\n[[\"0.12.9\".changes]]\nchange_id = \"name-free-side-set\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new free function `name_free_side_set` to `salvus_mesh_utils`. This\nfunction finds all mesh surfaces not currently assigned to a side set and either\na) creates a new side set with the name passed, assigning the found surfaces, or\nb) appends to an existing side set of the same name if it already exists in the\nmesh.\\\n\"\"\"\n\n[[\"0.12.9\".changes]]\nchange_id = \"handling-zero-offsets-in-point-to-linesource-conversion\"\nproduct = \"SalvusModules\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd safeguards to properly handle two edge cases in the point-to-linesource\nconversion utility.\\\n\"\"\"\n\n[[\"0.12.9\".changes]]\nchange_id = \"time-step-heuristic-for-sponge-layers\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new heuristic for computing the time step inside the sponge layers of the\nabsorbing boundaries. The previous logic required a more conservative choice\nof the Courant number to guarantee stability of the simulation.\\\n\"\"\"\n\n[[\"0.12.9\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSkip py39 tests on MR pipelines and ensure the default branch is tested before\nuploading to S3.\\\n\"\"\"\n\n[\"0.12.8\"]\nrelease_date = \"2022-11-21\"\nrelease_message = \"\"\"\nThis is a minor release featuring a few bug fixes and additions detailed below\nto improve usability and performance.\n\nAdditionally, several improvements to the internal meshing algorithms have\nbeen made.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nchange_id = \"bug-fix-chunkwise-source-reading\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nBug fix for reading in custom source time functions from hdf5 in SalvusCompute.\nThis could cause an interpolation error when providing input on an oversampled\ntime axis.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nConsistently use the same version number in SalvusPy and SalvusCompute and add\nvalidation to the CI.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nchange_id = \"chunkwise-job-submission-in-task-chains\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable chunkwise job submission in task chains.\n\nThe optional parameter `max_concurrent_chains` can be passed to the\n`TaskChainSiteConfig` to limit the maximum number of concurrent chains.\nNote that when using more than one site, this parameter has to be consistent\nfor all sites in the current implementation.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nchange_id = \"cancel-simulations-in-project\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd ability to cancel ongoing or pending simulations in a project.\n\nExample:\n```python\np.simulations.cancel(\n  simulation_configuration=\"my_simulation\",\n  events=p.events.list()\n)\n```\n\nAlternatively, `p.simulations.cancel_all()` will cancel all simulations from\nthe simulations store.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nchange_id = \"speed-up-mesh-masking\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nPerformance improvement in `apply_element_mask`, which can lead to significant\nspeed-ups for meshes that neither have nodal parameters nor layered topography.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nchange_id = \"enable-volume-output-for-fourier-domain\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable new field `frequency-domain` for (time-dependent) volume and surface\ndata. In combination with the static frequency-domain output, this enables\nstoring the time-evolution of the discrete Fourier transform with the\npolynomial degree of the SEM shape functions.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nchange_id = \"output-assignment-for-got\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable optional additional outputs when computing the optimal transport misfit.\nIf requested, the distance matrix and the optimal assignment will be returned,\nwhich is useful for visualizing the optimal transport map.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nchange_id = \"customizable-shebang-slurm\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThere is a a new `job_script_shebang` setting for Slurm sites to allow\noverwriting the job script shebang.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd preliminary deep hashing implementation.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for anisotropic elements_per_wavelength in the `MeshResolution` object.\nOne can now either pass a scalar (isotropic) or a tuple (potentially\nanisotropic) when constructing the `MeshResolution`. If a tuple is passed of a\nlength lower than the number of dimensions in the mesh, the last entry in the\ntuple is repeated to fill any missing dimensions. Ordering of tuples passed\nshould follow the canonical (alphabetical) coordinate ordering.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix a bug where the `max_vertical_oversampling_factor` was not passed on to the\nintralayer refinement optimizer. Also changed the default from 1 to 2. This\nshould have negligible performance impacts but be appropriate now for pretty\nextreme variations in n_elem as well (i.e. in Dam Seis).\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nSeveral performance improvements for the layered mesher, and the beginnings of a\nways to specify local refinements.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFixed a bug and improved qol for the LM.  Bug: Intralayer refinements need to\nbe constrained to +/- 1 elements in the horizontal directions and 2 along the\naxes in 3-D.  QOL: Interface interpolations are now automatically clipped to the\npassed coordinates to avoid floating point issues at the boundaries.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nproduct = \"SalvusUtils\"\npublic_change = false\ndescription = \"\"\"\nAllow for proper handling of variadic positional arguments in type validators /\nprojectors.\\\n\"\"\"\n\n[[\"0.12.8\".changes]]\nproduct = \"SalvusUtils\"\npublic_change = false\ndescription = \"\"\"\nImplement \"projections\" as a modification of type validators. Projections let\nyou generically cast input types to other types before a function is called. See\nlike 387+ in test_type_validators.py for some examples. Hopefully will reduce\nboilerplate.\\\n\"\"\"\n\n[\"0.12.7\"]\nrelease_date = \"2022-10-12\"\nrelease_message = \"\"\"\nThis is a minor bugfix / maintenance release that makes a few of the internal\nmeshing algorithms more robust.\\\n\"\"\"\n\n[[\"0.12.7\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for fixed horizontal element positions in the layered mesher.\\\n\"\"\"\n\n[[\"0.12.7\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for overriding the layered model interpolation in `mesh_from_domain`.\\\n\"\"\"\n\n[[\"0.12.7\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nInitialize a special case of the interface spline extender that allows an\ninterface to be extended in a straight line to the end of the domain.\\\n\"\"\"\n\n\n[\"0.12.6\"]\nrelease_date = \"2022-09-29\"\nrelease_message = \"\"\"\nNew features introduced with this release include callback functions\nto implement event-dependent meshes and iteration-dependent event\nselections for mini-batch inversions. Furthermore, an initial implementation\nof a new workflow for computing forward simulations, misfits and gradients\nwithin a single chain of tasks is introduced.\n\nAdditionally, the release contains various minor bug fixes and small\nimprovements  listed below.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd some regression tests and remove warnings for anisotropic acoustic 3D.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nPropagate absorbing boundaries to the mesh file in the layered mesher.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nPropagate fluid flag properly for acoustic anisotropic materials.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for higher order model interpolation in the layered mesher.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nGeneralize doubling and tripling algorithms.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nRemove deepcopy from LM material construction.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"axis-aligned-abs-bound\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAllow for an axis-aligned shortcut for absorbing boundary attachment. Useful in\ncartesian domains, and specified via passing \"side_sets_are_axis_aligned\" to\nthe simple config `AbsorbingBoundary` constructor.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"use-copyfile\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nUse `shutil.copyfile()` instead of `shutil.copy()` and `shutil.copy2()` to\navoid problems copying between file systems with and without permission bits.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd the reference frame global string to meshes generated with the layered\nmesher.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"resilient-misfit-computation-faulty-processing\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe data selection can now properly deselect data whose processing raises an\nexception for only a few receivers. This usually only happens with faulty\nreceiver metadata.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"ipywidgets-8-0-0\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nUpgrade to `ipywidgets>=8.0.0`. The changes are backward compatible with older\nversions of `ipywidgets`.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"task-chain-integration-with-inversion\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nInitial implementation of task chains for solving inverse problems.\nThe `job_submission` settings can now optionally receive a `TaskChainSiteConfig`\nto compute misfits in parallel, and to chain forward and adjoint simulations.\n\nThis is an experimental feature which is currently restricted to remote sites\nwhich share the same file system and the DataBlockIO backend of events.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"improve-control-group-handling\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd functionality to check the trial model on subsets of events (including\nnone). The list can be adjusted by using the optional argument\n`control_group_events` in the constructor of an iteration.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"chunkwise-job-submission-for-inversion-actions\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew optional parameter `max_events_per_job_submission` for inversion action\ncomponent to limit the maximum number of events that are simultaneously\nsubmitted per job to reduce the memory overhead.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"dynamic-event-selection\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd an optional callback function `event_batch_selection` to the\n`InverseProblemConfiguration`, which allows to define an iteration-dependent\nselection of events and/or control group to check the trial model only for a\nsubset of events.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"event-dependent-meshes\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImplement gradient mapping for event-dependent meshes to enable their use\nfor inversions.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"trust-region-single-gradient-strategy\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd new option `use_event_dependent_gradients` for the trust-region method.\nWhen set to `True`, only the accumulated gradient for all events is used, and\ntasks of type `TaskMisfitsAndSummedGradient` are issued instead of\n`TaskMisfitsAndGradients`.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"mitigate-nfs-file-handles\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nMitigate open nfs file handles when deleting simulation results.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"integrate-event-dependent-meshes-in-task-chains\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nIntegrate using event-dependent meshes with task chains.\nThis also adds a faster way to compute misfits without gradients.\\\n\"\"\"\n\n[[\"0.12.6\".changes]]\nchange_id = \"piecewise-discontinuous-model-blocks\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new option for `discontinuous_model_blocks` to the mapping function.\nWhen used in combination with a `homogeneous` scaling, this function allows\nfor the parameterization of piecewise constant models.\\\n\"\"\"\n\n\n[\"0.12.5\"]\nrelease_date = \"2022-08-25\"\nrelease_message = \"\"\"\nMinor release containing several performance improvements in handling FWI\nworkflows and a few bug fixes. Details are listed below.\n\nFrom this version onward, Salvus drops support for Centos6 and older systems.\\\n\"\"\"\n\n\n[[\"0.12.5\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd a intralayer vertical refinement policy.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllow for partitioning with an externally-defined interface.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"blockwise-data-processing\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd new interal functionality to efficiently operate on structured receiver data.\nThis includes resampling, tapering, and padding.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd 2-D anisotropic acoustic material parameters to the layered mesher.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdd 3-D anisotropic acoustic material parameters to the layered mesher.\nParametrization is currently a work in progress.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"event-blocks\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew event block data structure to more efficiently deal with large-scale\nacquisition geometries and a corresponding way to deal with them in\nSalvus*Project*.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"external-data-proxies\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nGeneralized external data proxies to read data from arbitrary external data\nsources without copying them into a Project.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"seis-io\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAssorted file format utilities, helpers, and converters.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nThe type validator now works with basic union types and optional arguments.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"task-chain-controller\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew task chain controller and runner primitives to efficiently steer and\nparallelize a large collection of task chains across different machines.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"validate-side-sets-in-input-file-generation\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAutomatically validate that all side-sets required for surface output or\nboundary conditions are contained in the mesh.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"bug-fix-mesh-widget\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nTwo small bug fixes in the mesh widget. The colorbar is now properly scaled\nfor nearly constant parameter fields. Furthermore, it is possible to switch\nparameter fields while the side-sets toggle is active, which previously raised\nan error.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"event-dependent-meshes\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImplement a masking function as an optional callback of the simulation\nconfiguration. This enables using event-dependent meshes for forward\nsimulations. This feature is currently not supported for assembling gradients.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"bug-fix-event-sorting\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug which could cause simulation results ending up in the wrong\ndirectory when the event names were not padded with zeros.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"performance-improvements-misfit-workflows\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nPerformance improvements for misfit computation workflows in projects with\na large number of events.\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"dropping-support-for-centos6\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFrom this release onwards the oldest supported CentOS version is Centos7.\nSalvus will not run on Linux systems with an older libc anymore.\n\nCentos6 reached End of Life (EOL) in November 2020. In case you still have a need\nfor running Salvus on an old operating system, please get in touch with\nsupport@mondaic.com\\\n\"\"\"\n\n[[\"0.12.5\".changes]]\nchange_id = \"bugfix-anisotropic-elastic-3d\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the material parameterization of 3D anisotropic elastic material.\nWhen using the full tensor (Cij) it is no longer necessary to pass a symmetry\naxis with the mesh.\\\n\"\"\"\n\n[\"0.12.4\"]\nrelease_date = \"2022-07-28\"\nrelease_message = \"\"\"\nMinor release that brings in support for using strain and gradient measurements\nin full-waveform inversion. Furthermore, the ability to read (adjoint) sources\nin chunks was added to alleviate the memory requirements for simulations with\nmany sources or time steps.\n\nThere are a few more small improvements and bug fixes listed below.\\\n\"\"\"\n\n\n[[\"0.12.4\".changes]]\nchange_id = \"scientific-number-format-in-processing\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the bandpass processing fragment, which did not recognize\nfrequency inputs in scientific number format.\n\nHere is an example of a data name:\n\n```python\n\"EXTERNAL_DATA:raw_data | bandpass(1.0e3, 2.0e3) | normalize\"\n```\\\n\"\"\"\n\n[[\"0.12.4\".changes]]\nchange_id = \"strain-misfits-and-adjoint-sources\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable the use of misfits and adjoint sources based on first spatial\nderivatives of the wavefield, i.e., strains and gradients.\n\nIt is now possible to also pass `strain`, `gradient-of-displacement` and\n`gradient-of-phi` as valid receiver fields in the misfit configuration and\nrelated event data and event misfit objects.\n\nRemember that strain data are not rotated and output is in Cartesian\ncoordinates.\\\n\"\"\"\n\n[[\"0.12.4\".changes]]\nchange_id = \"rename-gradient-channels-in-asdf\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nRename datasets (and derived channel names) in ASDF output for gradients of the\ndisplacement field to comply with the SEED convention.\n\n**This is a (small) breaking change that only affects the combination of ASDF\nfiles with outputting the gradient of the displacement field.**\n\nThe names of datasets and channels need to be adjusted as follows:\n\n2D (old): `XXX`, `XXY`, `XYX`, `XYY`\n\n2D (new): `XG0`, `XG1`, `XG2`, `XG3`\n\n3D (old): `XXX`, `XXY`, `XXZ`, `XYX`, `XYY`, `XYZ`, `XZX`, `XZY`, `XZZ`\n\n3D (new): `XG0`, `XG1`, `XG2`, `XG3`, `XG4`, `XG5`, `XG6`, `XG7`, `XG8`\n\nApologies for the inconvenience caused.\\\n\"\"\"\n\n[[\"0.12.4\".changes]]\nchange_id = \"bug-fix-viz-waveforms\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in `p.viz.waveforms()`, which caused to function to fail with a\ncryptic error message when `data` was passed as a string.\\\n\"\"\"\n\n[[\"0.12.4\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate image for python deploy to manylinux 2010.\\\n\"\"\"\n\n[[\"0.12.4\".changes]]\nchange_id = \"slurm-omit-tasks-per-node\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew `omit_tasks_per_node` setting for Slurm sites.\n\nThis will cause the `ntasks-per-node` to be omitted for both the `#SBATCH`\ncommand as well as the call to `srun` for the rare site where this is\nnecessary.\\\n\"\"\"\n\n[[\"0.12.4\".changes]]\nchange_id = \"src-chunking\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSupport the partial loading of sources into memory. Can be important for\nsimulations with lots of sources and / or a long duration.\\\n\"\"\"\n\n[[\"0.12.4\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nOpen up a new meshing interface based on layered models. This API is currently\nunstable, and may change in the future without warning.\\\n\"\"\"\n\n[\"0.12.3\"]\nrelease_date = \"2022-07-03\"\nrelease_message = \"\"\"\nThis release introduces new modules or improved support for several physics in\nthe simulation engine. This includes anisotropic acoustic media, native\nsupport for visco-acoustic simulations, and a new solver model for static\nproblems to solve the Poisson equation. Some of the new features are currently\nonly supported on CPU hardware.\n\nAdditionally, the release enables custom MPI commands, for instance\nto use machine files on remote machines and contains several small bug fixes.\\\n\"\"\"\n\n[[\"0.12.3\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nOptional build and tests for py39 including a few fixes in the tests.\\\n\"\"\"\n\n[[\"0.12.3\".changes]]\nchange_id = \"vti-acoustic\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSupport waveform simulations and gradients w.r.t. medium properties in\nVTI acoustic media.\\\n\"\"\"\n\n[[\"0.12.3\".changes]]\nchange_id = \"visco-acoustic\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSupport visco-acoustic modeling in the scalar wave equation.\nThe implementation and API are very similar to visco-elastic modeling, and\nrequire the specification of linear solids and `QKAPPA` as a material\nparameter.\n\nPreviously, attenuation in a fluid could only be modeled as a degenerate case\nof elastic physics.\n\nThis feature is currently only supported on CPUs and SalvusCompute will\nthrow an error when attempting to run a visco-acoustic simulation on a\nCUDA-enabled site.\\\n\"\"\"\n\n[[\"0.12.3\".changes]]\nchange_id = \"poisson-solver\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new physics module to solve the Poisson equation.\n\nThis is the first elliptic PDE that can be solved with Salvus.\nThe Poisson equation is useful for simulatingthe gravitational potential\nof a planetary object as well as computing correct inner products and\nregularization terms in the Sobolev space $H^1$.\n\nThis feature is currently only supported on CPUs and is considered\nexperimental.\\\n\"\"\"\n\n\n[[\"0.12.3\".changes]]\nchange_id = \"unstructured-mesh-sim-config-ec-changes\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nChanges to the event configuration in `UnstructuredMeshSimulationConfiguration`\nobjects are now properly recognized when trying to overwrite an existing\nconfiguration of the same name.\\\n\"\"\"\n\n[[\"0.12.3\".changes]]\nchange_id = \"segy-events\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nExtend functionality of handling segy files for adding external data to a\nproject.\n\nInstead of just passing the source mechanism, users can now define simple\ncallback functions for sources and receivers to create Salvus objects from\nthe information stored in segy files. This breaks the previous syntax of\nthe implementation of `SegyEvent`, but it should be straightforward to\nupgrade.\\\n\"\"\"\n\n[[\"0.12.3\".changes]]\nchange_id = \"remote-io-site-error-handling\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nMinor improvement in the SSH connection error handling. It should now report\na better error message.\\\n\"\"\"\n\n[[\"0.12.3\".changes]]\nchange_id = \"extra-paramiko-args\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nExtra keyword arguments can now be passed to `paramiko.SSHClient.connect()`\nto allow more fine tuning for some SSH connections.\n\nUsage in the site config file:\n\n```toml\n[sites.my_site.ssh_settings]\n    hostname = \"some_host\"\n    username = \"some_user\"\n    [sites.my_site.ssh_settings.extra_paramiko_connect_arguments.disabled_algorithms]\n        pubkeys = [\"rsa-sha2-512\", \"rsa2-sha2-256\"]\n```\n\nFurthermore the `init-site` command now has a `--verbose` flag to facilitate\ndebugging tricky connections:\n\n```shell\nsalvus-cli init-site my_site --verbose\n```\\\n\"\"\"\n\n[[\"0.12.3\".changes]]\nchange_id = \"custom-mpirun-handling\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nA new `mpirun_template` parameter for `ssh` and `local` site types that allows\nfull customization of the actual call to `mpirun` in case it is necessary.\n\nUsage in the site config file:\n\n```yaml\n[sites.my_site.site_specific]\n    mpirun_template = \"/custom/mpirun -machinefile ~/mf -n {RANKS}\"\n```\n\nThis example will thus use a custom `mpirun` executable with a non-standard\nargument for all Salvus runs on that site. The `{RANKS}` argument will be\nfilled in by Salvus with the number of ranks for each simulation.\\\n\"\"\"\n\n[\"0.12.2\"]\nrelease_date = \"2022-05-31\"\nrelease_message = \"\"\"\nMinor update with a new model class based on xarray\nto invert for structured data in SalvusOpt. Furthermore,\nwe extended the options for passing callback functions to\nSalvusProject.\\\n\"\"\"\n\n[[\"0.12.2\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nTwo small changes to get Salvus ready for py39.\\\n\"\"\"\n\n[[\"0.12.2\".changes]]\nchange_id = \"structured-model-salvus-opt\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd new model class `StructuredModel` to SalvusOpt to invert models\nparameterized on a regular grid using xarray.Datasets.\\\n\"\"\"\n\n[[\"0.12.2\".changes]]\nchange_id = \"better-function-serialization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe function serialization can now also deal with functions passed in\nclosures.\\\n\"\"\"\n\n[\"0.12.1\"]\nrelease_date = \"2022-05-16\"\nrelease_message = \"\"\"This release provides several small improvements\nfor making inversion workflows more resilient and more robust.\n\nFurthermore, we added easier support for arbitrary boundary conditions\nthrough the `WaveformSimulationConfiguration`.\\\n\"\"\"\n\n[[\"0.12.1\".changes]]\nchange_id = \"support-for-boundary-conditions-in-wsc\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd support for specifying boundary conditions in the\n`WaveformSimulationConfiguration`. This is useful for Dirichlet-type\nboundaries or absorbing boundaries of a\n`UnstructuredMeshSimulationConfiguration`.\nBoundaries specified here will be applied in addition to ocean load and/or\nabsorbing boundaries specified as `AbsorbingBoundaryParameters` in the\n`SimulationConfiguration`. A `ValueError` is raised for duplicated conditions\non a side set.\\\n\"\"\"\n\n[[\"0.12.1\".changes]]\nchange_id = \"performance-tracking-opt\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd basic timing statistics for the tasks of an iteration.\nA summary is printed in the `Stats` tab of the iteration widget.\\\n\"\"\"\n\n[[\"0.12.1\".changes]]\nchange_id = \"reduce-memory-overhead-of-gradient-handling\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nReduce the memory overhead of dealing with many event-dependent gradients.\\\n\"\"\"\n\n[[\"0.12.1\".changes]]\nchange_id = \"better-error-handling-for-preconditioner\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd ability to recover from failed preconditioner tasks and provide error\nlogs of failed smoothing jobs.\\\n\"\"\"\n\n[[\"0.12.1\".changes]]\nchange_id = \"better-error-handling-for-failed-misfit-computations\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd ability to recover from failed misfit computations. If a misfit computation\nfails for one more events during `compute_misfits`, the simulation results are\nconsidered corrupted and will be automatically deleted. This means that those\nsimulations will be resubmitted when calling `compute_misfits` again.\n\nThis helps, for instance, to recover from corrupted ASDF files in case they have\nnot have been written or downloaded correctly.\\\n\"\"\"\n\n[[\"0.12.1\".changes]]\nchange_id = \"trace-by-trace-normalization\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd an normalization option for the misfit and adjoint source\ncomputation.\n\nThe adjoint source is aware of this operation and Salvus will make sure it is\ncorrect.\\\n\"\"\"\n\n\n[\"0.12.0\"]\nrelease_date = \"2022-04-30\"\nrelease_message = \"\"\"This is a new major release which comes with a big\nportion of internal changes.\n\nFortunately, there are only a few breaking changes on the user-facing API,\nwhich are mostly related to custom meshing functionality.\n\nWe've also used the opportunity to remove some deprecated functionality of the\ninversion component, and added several improvements related to resilience and\nperformance.\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nchange_id = \"remove-deprecated-job-submission-settings\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nRemove job submission settings from the inversion routines\n`iterate()` and `resume()`. Specifying `site_name`,\n`ranks_per_job` and `wall_time_in_seconds_per_job` is no longer\nsupported. Instead, the `job_submission_settings` either need to be passed to\nthe constructor of the `InverseProblemConfiguration` or by using\n`p.inversions.set_job_submission_configuration()`.\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nchange_id = \"speed-up-adjoint-mapping\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nPerformance improvement of the adjoint mapping function when using cutouts\naround source or receiver locations.\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nchange_id = \"fix-compression-handling\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd option to query simulations for specific compression settings.\n\nExample:\n```python\np.simulations.query(\n    simulation_configuration=\"my_simulation\",\n    misfit_configuration=\"my_misfit\",\n    wavefield_compression=sn.WavefieldCompression(\n        forward_wavefield_sampling_interval=15\n    ),\n    events=p.events.list(),\n)\n```\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nchange_id = \"add-mask-for-cartesian-volume-models\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the option to pass an element mask to Cartesian volume models. Useful, for\ninstance, when you only want to interpolate parameters onto a specific\nsubdomain of the mesh (i.e. only onto elastic elements).\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nChange reference from `salvus-flow` to `salvus-cli` in a number of places.\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nchange_id = \"reinit-ssh-on-closed-socket\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nWill now reinitialize the SSH site in case a socket has been closed.\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nchange_id = \"share-ssh-channel\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nBetter sharing of existing SSH connections. Should reduce the number of\nnecessary SSH connection reinitializations.\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nchange_id = \"model-overwriting\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that could occur in very specific circumstances when overwriting\nan existing bathymetry model.\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nchange_id = \"task-chain-timings\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded timings to the individual tasks of a `TaskChain`.\\\n\"\"\"\n\n[[\"0.12.0\".changes]]\nchange_id = \"mesh-block\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nRemoved the `StructuredGrid2D`, `StructuredGrid3D` and `Skeleton` classes and\nreplaced them with new `MeshBlock` and `MeshBlockCollection` classes.\n\nThis should have a minimal influence on most users - please contact us if\nyou experience any issues.\\\n\"\"\"\n\n[\"0.11.48\"]\nrelease_date = \"2022-03-30\"\nrelease_message = \"\"\"\nThis release contains a long-sought feature for reducing the memory footprint\nof checkpoints for adjoint simulations by sampling the forward wavefield on\na coarser grid during the adjoint run. **This includes breaking changes\nfor some of the inversion routines, which may require updating the syntax of\nsome notebooks.** Details are listed below. If you are concerned about\nupgrading, please get in touch with us in the user forum.\n\nThe release also contains bug fixes concerning the use of custom bm files\nin SalvusProject and attaching receivers on SmoothieSEM meshes, as well as\nthe option to provide a custom scaling for the mapping function of the\ninversion.\n\nAlso, don't forget to keep your python environment up-to-date!\nWe recommend to always run\n\n```bash\nwget https://mondaic.com/environment.yml -O ~/environment.yml\nconda env update -n salvus -f ~/environment.yml\n```\nbefore upgrading.\\\n\"\"\"\n\n[[\"0.11.48\".changes]]\nchange_id = \"custom-scaling\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd option for custom scaling in mapping function.\nThe custom scaling parameters need to be defined on the same mesh as the\nsimulation and provided as elemental fields for all parameters.\n\nExample\n```python\nmesh = p.simulations.get_mesh(\"sim\")\n\n# Modify scaling parameters for all fields\nmesh.elemental_fields[\"VP\"] = ...\nmesh.elemental_fields[\"RHO\"] = ...\n\nm = Mapping(\n  scaling=mesh,\n  inversion_parameters=[\"M\"],\n  map_to_physical_parameters={\"VP\": \"M\", \"RHO\": \"M\"},\n)\n```\\\n\"\"\"\n\n[[\"0.11.48\".changes]]\nchange_id = \"bm-file-serialization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nAdd proper serialization of bm files in SalvusProject.\nPreviously, custom bm files were not added to the project and relied on\nexternal paths which prevented copying projects to other machines.\n\nAdding custom background models as string will now throw a deprecation warning.\nIt is strongly recommended to add custom bm files using the class\n`model.background.one_dimensional.FromBm`.\\\n\"\"\"\n\n[[\"0.11.48\".changes]]\nchange_id = \"wavefield-compression\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nAdd option for wavefield compression during adjoint runs to reduce the\nmemory overhead. In order to allocate the correct number of checkpoints,\nthis setting needs to be available at the time of computing the forward\nwavefield.\nThis setting can now be used in several locations listed below by adding\n\n```python\nsn.WavefieldCompression(\n      forward_wavefield_sampling_interval=N\n  )\n```\nif checkpoints should be stored for a resampling interval of `N` during the\nadjoint run.\n`forward_wavefield_sampling_interval=1` corresponds to no compression and is\nequivalent to what was done prior to this release.\n\n**This is a (small) breaking change that requires updating the syntax of\ninversion-related functionality!**\n\n**new optional arguments:**\n\nThe wavefield compression settings enter now as _optional_ argument into\nsome objects and functions.\nIf not given, it will default to `forward_wavefield_sampling_interval=1`,\nwhich is consistent with Salvus `<= 0.11.47`.\n\nExamples:\n\n```python\n# Inversion actions:\np.action.inversion.compute_misfits(\n  ...,\n  derived_job_config=sn.WavefieldCompression(\n      forward_wavefield_sampling_interval=5\n  ),\n  ...\n)\n\np.action.inversion.compute_gradients(\n  ...,\n  wavefield_compression=sn.WavefieldCompression(\n      forward_wavefield_sampling_interval=5\n  ),\n  ...\n)\n\np.action.inversion.sum_gradients(\n  ...,\n  wavefield_compression=sn.WavefieldCompression(\n      forward_wavefield_sampling_interval=5\n  ),\n  ...\n)\n\n# InverseProblemConfiguration\nsn.InverseProblemConfiguration(\n  ...\n  wavefield_compression=sn.WavefieldCompression(\n      forward_wavefield_sampling_interval=5\n  ),\n  ...\n)\n```\n\n**deprecated parameters:**\n\nThe parameters `store_adjoint_checkpoints` in `p.simulations.launch(...)` and\n`store_checkpoints` in `p.actions.inversion.compute_misfits(...)` are\ndeprecated. Instead, use\n\n```python\n  derived_job_config=WavefieldCompression(\n      forward_wavefield_sampling_interval=N\n  ),\n```\n`derived_job_config=None` is the new default, which corresponds\nto the deprecated `store_adjoint_checkpoints=False` or\n`store_checkpoints=False`, respectively.\n\n\n**breaking changes:**\n\n`compute_misfits` and `compute_gradients` in `p.action.inversion` are now\nkeyword-only functions. Additionally, we made the wavefield compression\nsettings mandatory arguments of a few lower-level functions, such as:\n\n```python\np.misfits.get_gradient_filenames()\np.simulations.get_adjoint_input_files()\np.action.validation.validate_model_gradients()\n```\n\nIn case you are using one of these directly, you will notice an error like\n\n```python\nTypeError: compute_gradients() needs keyword-only argument\nwavefield_compression\n```\n\nwhich can be fixed by just adding the wavefield_compression object shown\nabove.\\\n\"\"\"\n\n[[\"0.11.48\".changes]]\nchange_id = \"task-chains\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew `TaskChain` workflow primitive that can be used to run multiple Salvus jobs\nand/or Python scripts in a linear chain within a single local/ssh/HPC job.\n\nThis is a first implementation so expect some rough edges:\n\n```python\n# Construct a forward simulation object.\nw_forward = sn.simple_config.simulation.Waveform(\n    ..., store_adjoint_checkpoints=True\n)\n\n# Construct an adjoint simulation object.\nw_adjoint = sn.simple_config.simulation.Waveform(...)\n...\n# There is a new `PROMISE_FILE:` prefix to tell SalvusFlow that a file does\n# not exist yet but it will exist when the simulation is run.\nw_adjoint.adjoint.point_source_block = {\n    \"filename\": \"PROMISE_FILE:task_2_of_2/input/adjoint_source.h5\",\n    \"groups\": [\"adjoint_sources\"],\n}\n\n# Define a Python function that is run between forward and adjoint simulations\n# to generate the adjoint sources.\ndef compute_adjoint_source(\n    task_index: int, task_index_folder_map: dict[int, pathlib.Path]\n):\n    folder_forward = task_index_folder_map[task_index - 1]\n    folder_adjoint = task_index_folder_map[task_index + 1]\n\n    output_folder = folder_forward / \"output\"\n\n    event = sn.EventData.from_output_folder(output_folder=output_folder)\n\n    event_misfit = sn.EventMisfit(\n        synthetic_event=event,\n        misfit_function=\"L2_energy_no_observed_data\",\n        receiver_field=\"displacement\",\n    )\n\n    input_folder_adjoint = folder_adjoint / \"input\"\n    event_misfit.write(input_folder_adjoint / \"adjoint_source.h5\")\n\n\n# Launch the task chain. It will serialize the Python function and launches\n# everything either locally or in Slurm/other supported systems.\ntc = sn.api.run_task_chain_async(\n    site_name=\"local\",\n    tasks=[w_forward, compute_adjoint_source, w_adjoint],\n    ranks=4,\n)\n# Wait until it finishes.\ntc.wait()\n```\\\n\"\"\"\n\n[[\"0.11.48\".changes]]\nchange_id = \"receiver-placement-fixes\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nMore stable implementation of the rewritten receiver placement and it should\nnow also work for highly distored meshes.\\\n\"\"\"\n\n[[\"0.11.48\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nThe salvus upgrade message now contains instructions on how to keep a conda\nenvironment up-to-date.\\\n\"\"\"\n\n[\"0.11.47\"]\nrelease_date = \"2022-03-23\"\nrelease_message = \"\"\"\nMinor update to patch a bug introduced with 0.11.46.\\\n\"\"\"\n\n[[\"0.11.47\".changes]]\nchange_id = \"fix-bug-in-serialization-of-unstructured-mesh-simulation-configs\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug introduced with 0.11.46, which broke backward compatibility of a\nproject when deserializing an `UnstructuredMeshSimulationConfiguration`.\\\n\"\"\"\n\n[\"0.11.46\"]\nrelease_date = \"2022-03-18\"\nrelease_message = \"\"\"\nThis release comes with a fairly long list of small improvements and bug fixes\nlisted below.\nNotable new features include (full) gradient sources for elastic simulations,\nGPU support for acoustic gradient sources, better memory management of\ninversions, several tweaks regarding window selection and weighting,\nand a more robust and faster algorithm to attach receivers.\n\nThanks again to all users who reported bugs and requested features!\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"clear-adjoint-caches\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSafely remove adjoint sources after the adjoint simulation.\nThis happens automatically after retrieving the results from the adjoint\nsimulation. Adjoint source files will be recomputed on-the-fly if required.\nThis can also be done explicitly using\n\n```python\np.misfits.compute_adjoint_source()\n```\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"bugfix-adjoint-hashes\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the hash computation for adjoint simulations that could\nresult in non-unique hashes in special cases.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"use-default-ranks-for-init-site\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nInitializing a site with SalvusFlow now runs a test job using the\ndefault number of ranks for that site instead of 2.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\npublic_change = false\nproduct = \"SalvusFlow\"\ndescription = \"\"\"\nBegin to implement modularization of SalvusJob objects.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\npublic_change = false\nproduct = \"SalvusCompute\"\ndescription = \"\"\"\nPreliminary gradient subsampling implementation.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\npublic_change = false\nproduct = \"SalvusCompute\"\ndescription = \"\"\"\nFix gradient subsampling bug.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"change-receiver-weight-map\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew default basemap for the seismology receiver weights and misfit maps.\nFurthermore they are now configurable.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"allow-expressions-in-grid-engine-and-pbs-values\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe site configuration for the GridEngine and PBS site types now allows\nsimplistic expressions:\n\n```toml\n  [[sites.site_name.site_specific.additional_qsub_arguments]]\n      name = \"pe\"\n      value = \"mpi {NODES * TASKS_PER_NODE}\"\n\n  [[sites.site_name.site_specific.additional_qsub_arguments]]\n      name = \"l\"\n      value = \"ngpus={int(ceil(RANKS / 12))}\"\n```\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"bug-fix-window-picking-log-output\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe error log output of the seismological window picking routine is now more\ndescriptive.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"no-ewws-for-no-windows\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvusProject will no longer create an empty `EventWindowAndWeightSet` in case\nthe window selection routine did not pick a single window for a chosen event.\n\nAn appropriate warning message and log file entry will be created in that\ncase.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"new-seismology-action-get-windows\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew function to get all events with windows for a chosen data selection\nconfiguration:\n\n```python\np.actions.seismology.get_events_with_windows(\"DSC_NAME\")\n```\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"deal-with-zero-weights\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded some more receiver weight validation steps and Salvus now properly deals\nwith a few more edge cases, for example when the total receiver weight sum of\nan event is zero.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"crs-helper-method\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new `lat_lng_to_utm_crs()` helper routine to directly get a pyproj UTM\nCRS object from a point given in latitude and longitude.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"remove-ellipsoid\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\n`UTMDomain` objects no longer require the ellipsoid to be passed.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"relative-location-improvements\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe relative source and receiver placement code is much faster now due to\nalgorithmic changes and code optimizations. Additionally, a few previously\nuncaught edge cases now work as expected.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"vector-gradient-sources\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded vector gradient sources for elastic media.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"scalar-gradient-gpu\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nScalar gradient sources now also work on GPUs.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"local-hpc-sites\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded local version of all HPC sites that directly interact with the job\nqueuing and file systems without using SSH.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\npublic_change = false\nproduct = \"SalvusFlow\"\ndescription = \"\"\"\nMuch faster import time for the cli module by reducing global imports.\\\n\"\"\"\n\n[[\"0.11.46\".changes]]\nchange_id = \"salvus-cli-cmd\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew `salvus-cli` alias for the `salvus-flow` command line call. This will\nbecome the default at one point.\\\n\"\"\"\n\n[\"0.11.45\"]\nrelease_date = \"2022-01-27\"\nrelease_message = \"\"\"\nFirst release of 2022 with several small bug fixes listed below.\nAs a new feature, SalvusProject supports multiple source time functions for\ndifferent point sources, which facilitates simulating finite faults or\nencoded sources.\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nchange_id = \"fix-bug-in-gradient-widget\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the gradient view of the iteration widget.\nNow the mapped gradient accumulated from all events is correctly displayed in\nthe widget.\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nchange_id = \"enable-deserialization-after-site-change\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that prevented loading an `InverseProblemConfiguration` after\nthe project has been transferred to another python environment with a\ndifferent site configuration.\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nchange_id = \"multiple-wavelets-for-multiple-point-sources\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable different source time functions for event with multiple point sources.\n\nExample:\n```python\n\nEvent(\n  event_name=\"event\",\n  sources=[point_src1, point_src2],\n  receivers=receivers,\n)\n\n...\n\nEventConfiguration(\n  waveform_simulation_configuration=...,\n  wavelet=[\n      simple_config.stf.Ricker(center_frequency=1.0),\n      simple_config.stf.Ricker(center_frequency=2.0),\n  ],\n)\n```\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nReplace libdate dependency from `tz.h` with `date.h` in SalvusCompute.\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nchange_id = \"fix-salvus-flow-upgrade-for-f64\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable `salvus-flow upgrade` and `salvus-flow upgrade-site` for\ndouble precision versions using the `salvus_f64` binary.\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nchange_id = \"init-site-wait-for-stderr\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `init-site` script will wait a bit longer for the `stderr` in case it is\nnot yet available due to some synchronization delays on shared and parallel\nfile systems.\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nchange_id = \"higher-order-2d-side-set-extrude\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `UnstructuredMesh.extrude_side_set_2D()` method now also works as expected\nfor higher order meshes. Additionally fixed an issue with inverted elements\nin certain scenarios.\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nchange_id = \"2d-anisotropic-absorbing-boundaries\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nBugfix for the Clayton-Enquist absorbing boundaries in 2-D anisotropic\nphysics.\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nThe dev version of the Python package now also work with \"dirty\" tagged\nversions.\\\n\"\"\"\n\n[[\"0.11.45\".changes]]\nchange_id = \"skip-half-timestep-of-elastic-fields-if-possible\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixes a performance bug for adjoint GPU runs in purely elastic media. In this\ncase, an unnecessary serial step is now skipped when loading checkpoints.\\\n\"\"\"\n\n[\"0.11.44\"]\nrelease_date = \"2021-12-06\"\nrelease_message = \"\"\"\nMinor release with a few bug fixes listed below.\n\nShoutout to the user community for identifying these bugs\nand helping us to fix them.\\\n\"\"\"\n\n[[\"0.11.44\".changes]]\nchange_id = \"fix-shotgather-for-single-data-names\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in plotting shotgathers for single data series.\n\nExample:\n```python\np.viz.shotgather(\n    data=\"simulation\",\n    event=\"event\",\n    receiver_field=\"phi\",\n    component=\"A\"\n)\n```\\\n\"\"\"\n\n[[\"0.11.44\".changes]]\nchange_id = \"fix-float-casting-receiver-deserialization\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in (de)-serialization of receiver objects when accidentially passing\n`int` instead of `float` types.\\\n\"\"\"\n\n[[\"0.11.44\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix wheel contents which suddenly failed on Linux.\\\n\"\"\"\n\n[[\"0.11.44\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nThe dev version number complies with PEP 440.\\\n\"\"\"\n\n[[\"0.11.44\".changes]]\nchange_id = \"adjoint-source-plot-bug-fix\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixing a bug when plotting adjoint sources.\\\n\"\"\"\n\n[[\"0.11.44\".changes]]\nchange_id = \"fix-overlapping-surface-output\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug for CPU sites where surface output with multiple side sets per element\ncould cause an issue in the surface wavefield output ordering.\\\n\"\"\"\n\n[[\"0.11.44\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nMinor changes for SWPNoise.\\\n\"\"\"\n\n\n[\"0.11.43\"]\nrelease_date = \"2021-10-21\"\nrelease_message = \"\"\"Minor update with a bug fix for serializing cythonized\nfunctions.\\\n\"\"\"\n\n[[\"0.11.43\".changes]]\nchange_id = \"fix-cythonized-function-serialization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe function serialization can now serialize cythonized functions imported\nfrom other modules.\\\n\"\"\"\n\n[[\"0.11.43\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nIgnore the jupyter_client warning that is raised currently with up-to-date\nversions of everything.\\\n\"\"\"\n\n[\"0.11.42\"]\nrelease_date = \"2021-10-19\"\nrelease_message = \"\"\"Minor update with some internal changes and\nsupport for frequency domain output in Salvus project.\\\n\"\"\"\n\n[[\"0.11.42\".changes]]\nchange_id = \"fft-output-in-project\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd support for frequency-domain output to Salvus project.\n\nOptional output of the Fourier transform for a discrete set of frequencies\ncan now be passed as `extra_output_configuration` to the launch function.\n```python\np.simulations.launch(\n    ranks_per_job=4,\n    site_name=\"local\",\n    events=p.events.list(),\n    simulation_configuration=\"simulation\",\n    extra_output_configuration={\n        \"frequency_domain\": {\n            \"fields\": [\"displacement\"],\n            \"frequencies\": [1.0, 2.0, 3.0],\n        }\n    },\n)\n```\\\n\"\"\"\n\n[[\"0.11.42\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nMore descriptive error message in case the link checker in\n`validate_dynamic_libraries.py` fails.\\\n\"\"\"\n\n[[\"0.11.42\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdapting to changed in distutil as it no longer ships with 2to3.\\\n\"\"\"\n\n[\"0.11.41\"]\nrelease_date = \"2021-10-08\"\nrelease_message = \"\"\"This is a large release that adds many features useful for\nthe inversion of seismic data, particularly for land and near-surface\napplications.\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"negative-values-in-mesh-widget\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that caused the mesh widget to crash for fields with only negative\nvalues.\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdapt a test to pyproj 3.2.1.\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"graph-space-optimal-transport\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded an implementation of a graph space optimal transport misfit measure as\nintroduced in this paper:\n\n> *L. Métivier, R. Brossier, Q. Mérigot, and E. Oudet*. 2019.\n>\n> **\"A graph space optimal transport distance as a generalization of Lp  distances: application to a seismic imaging inverse problem\"**\n>\n> Inverse Problems, Volume 35, Number 8, [https://doi.org/10.1088/1361-6420/ab206f](https://doi.org/10.1088/1361-6420/ab206f)\n\nYou can use it by choosing `\"graph_space_optimal_tranport\"` everywhere Salvus\naccepts misfit functionals. The one tuning parameters is the\n`\"max_expected_time_shift\"` which, as the name implies, should be set to the\nmaximum expected time shift in seconds for individual wiggles between observed\nand synthetic data.\n\nFor many problems this can get completely avoid the cycle skipping problem.\nThis, admittedly manufactured, synthetic inversion example demonstrates the\npotential gains:\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"point-to-line-source-conversion\"\nproduct = \"SalvusModules\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded comprehensive support for converting data from a point source to an\nequivalent line source which is necessary for example when using 3-D observed\ndata in 2-D inversions.\n\nWe added a variety of different transform, each applicable in different use\ncases. Please have a look at the documentation for details.\n\n```python\nfrom salvus.modules.near_surface.processing import convert_point_to_line_source\n\nnew_st = convert_point_to_line_source(\n    st=st,\n    source_coordinates=[22.0, 1.0],\n    receiver_coordinates=[132.0, 0.0],\n    transform_type=\"single_velocity_exact\",\n    velocity_m_s=550.0\n)\n```\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"geophone-responses\"\nproduct = \"SalvusModules\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded utility functions to compute, remove, and plot geophone responses.\n\n```python\nimport numpy as np\nfrom salvus.modules.near_surface.processing import geophone_response\n\nfrequencies = np.logspace(0.1, 2, 2000)\nresponse = geophone_response.compute_geophone_response(\n    frequencies=frequencies,\n    geophone_frequency=4.5,\n    damping_ratio=0.4,\n    calibration_factor=11.2,\n)\ngeophone_response.plot_response(frequencies=frequencies, response=response)\n```\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"dict-and-numpy-array-closures\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe function serialization can now serialize numpy arrays and dictionaries as\nclosure values.\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"processing-fragments\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded the ability to use processing fragments to more easily perform some\nsimple and common processing techniques.\n\nTo for example bandpass and normalize some data use\n`\"EXTERNAL_DATA:raw_data | bandpass(1.0, 2.0) | normalize\"` as the data name.\n\nAvailable processing fragments:\n\n* `time_shift({SHIFT})`\n* `normalize`\n* `scale({FACTOR})`\n* `flip`\n* `bandpass({FREQ_MIN}, {FREQ_MAX}[, zerophase][, corners={CORNERS}])`\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"down-and-upsampling-during-adjoint-source-computation\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe observed and synthetic data can now optionally be downsampled before the\nmisfit and adjoint source are computed. The adjoint source is later upsampled\nagain and scaled correctly. Useful for expensive misfit functionals.\n\nIt can be used either at the event misfit level:\n\n```python\nevent_misfit = EventMisfit(\n    ...,\n    # Optionally downsample to the given number of npts.\n    max_samples_for_misfit_computation=max_samples_for_misfit_computation\n)\n```\n\nOr at the misfit configuration level within Salvus*Project*:\n\n```python\nmc = MisfitConfiguration(\n    ...,\n    # Optionally downsample to the given number of npts.\n    max_samples_for_misfit_computation=max_samples_for_misfit_computation\n```\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"3d-box-domain-visualization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded an automatic domain preview visualization for 3-D box domains.\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"improved-shotgather-visualization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded an improved shotgather visualization. Amongst other things, it can now\nplot interleaved data from multiple traces and sort the receivers with a lambda\nfunction:\n\n```python\np.viz.shotgather(\n    data=[\n        \"PROCESSED_DATA:corrected_data_10_15_hz | normalize\",\n        \"SYNTHETIC_DATA:starting_model_10_15_hz | normalize\",\n    ],\n    event=\"shot_049\",\n    receiver_field=\"velocity\",\n    component=\"Y\",\n    sort_by=lambda r: r.location[0]\n)\n```\\\n\"\"\"\n\n[[\"0.11.41\".changes]]\nchange_id = \"pass-interpolation-mode-to-mesh-from-xarray\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAllow for the passing of an interpolation mode to the `mesh_from_xarray`\nfunction in the Salvus Toolbox. This allows one to override the default spline\ninterpolation routine, which may be useful in the presence of strong velocity\ncontrasts.\\\n\"\"\"\n\n[\"0.11.40\"]\nrelease_date = \"2021-09-25\"\nrelease_message = \"\"\"This release contains improvements to the mesh-to-mesh\ninterpolation implementation, as well as a few fixes and quality-of-life\nimprovements to SalvusProject functionality and SalvusFlow database handling.\\\n\"\"\"\n\n[[\"0.11.40\".changes]]\nchange_id = \"compress-input-file-in-database\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAll input files are stored in Salvus' internal database. From now on these are\ncompressed which can safe a lot of space for input files with large number of\nreceivers. Existing databases will be automatically migrated to the new\nstructure.\\\n\"\"\"\n\n[[\"0.11.40\".changes]]\nchange_id = \"zoom-to-fit\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe domain map plots for spherical chunk and UTM domains now automatically zoom\nto fit upon loading.\\\n\"\"\"\n\n[[\"0.11.40\".changes]]\nchange_id = \"adapt-to-latest-appeears-changes\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nLess assumptions in the internal layout of AppEEARS DEM files so Salvus now\nworks with older and newer AppEEARS files.\\\n\"\"\"\n\n[[\"0.11.40\".changes]]\nchange_id = \"upgrade-mesh-to-mesh-algorithm\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove the mesh-to-mesh interpolation algorithm by allowing element set to be\nfurther restricted in both the source and destination meshes. This is useful,\nfor instance, when interpolating between meshes with oceans. Also improved the\nheuristic which decided which element to source parameters from if an element\nwas outside of the mesh or outside of a certain layer set. This should improve\nthe algorithm's stability in such cases.\\\n\"\"\"\n\n[\"0.11.39\"]\nrelease_date = \"2021-09-09\"\nrelease_message = \"\"\"This is a minor release that fixes a bug when applying\nanisotropic refinements to the crust in a global domain, and reduces the memory\nusage of some SalvusFlow routines.\\\n\"\"\"\n\n[[\"0.11.39\".changes]]\nchange_id = \"fix-undefined-delete-with-global-anisotropic-refinements\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug where an undefined reference to a refinement skeleton may be deleted\nbefore it was defined.\\\n\"\"\"\n\n[[\"0.11.39\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix broken links in mesher schema.\\\n\"\"\"\n\n[[\"0.11.39\".changes]]\nchange_id = \"reduze-filesize-to-transfer\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove detection of duplicated mesh files when transferring data of JobArrays\nto remote sites.\\\n\"\"\"\n\n[[\"0.11.39\".changes]]\nchange_id = \"lazy-read-of-mesh-objects-in-waveform-object\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nReduce memory usage of `simple_config.Waveform` objects by lazy evaluation of\nUnstructuredMesh objects.\\\n\"\"\"\n\n[\"0.11.38\"]\nrelease_date = \"2021-08-11\"\nrelease_message = \"\"\"\nMinor update with some utilities to inspect the contents of a project and\nto free up space during an inversion by deleting disposable files.\\\n\"\"\"\n\n[[\"0.11.38\".changes]]\nchange_id = \"cleanup-inversion-storage\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd utility to compress the storage requirements of an\ninversion by deleting files which are no longer needed\nand/or can be recomputed.\n\nExample:\n```python\np.inversions.delete_disposable_files(\n  inverse_problem_configuration=\"my_inversion\",\n  data_to_remove=[\"auxiliary\", \"waveforms\", \"gradients\"]\n)\n```\nNote that data from the initial model and unfinished iterations\nwill be kept. It is recommend to remove files in the order\n`auxiliary`, `waveforms`, `gradients`, because gradients are the most\nexpensive to recompute.\\\n\"\"\"\n\n[[\"0.11.38\".changes]]\nchange_id = \"delete-simulation-results\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd utility to delete simulation results (waveforms / gradients).\n\nExample:\n```python\n# Delete waveforms\np.simulations.delete_results(\n  simulation_configuration=\"my_sim_config\",\n  events=[\"event\"]\n)\n\n# Delete gradients\np.simulations.delete_results(\n  simulation_configuration=\"my_sim_config\",\n  misfit_configuration=\"my_misfit_config\",\n  events=p.events.list()\n)\n```\\\n\"\"\"\n\n[[\"0.11.38\".changes]]\nchange_id = \"viz-project-contents\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd utility to list a project's contents.\nThis function will be called automatically when a project is loaded.\\\n\"\"\"\n\n[\"0.11.37\"]\nrelease_date = \"2021-07-15\"\nrelease_message = \"\"\"\nThis is a small maintenance /bugfix release that primarily serves to activate\n2-D fully anisotropic elastic simulations on CUDA-capable GPUs.\\\n\"\"\"\n\n[[\"0.11.37\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nRemoving several unused functions.\\\n\"\"\"\n\n[[\"0.11.37\".changes]]\nchange_id = \"anisotropic-2d-on-gpu\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nActivate 2-D fully anisotropic simulations on CUDA capable GPUs, and fixes some\nbugs in the associated gradient computations. No API changes are required from\nusers -- simply feel free to now run 2-D anisotropic simulations and inversions\non a GPU-enabled site!\\\n\"\"\"\n\n[\"0.11.36\"]\nrelease_date = \"2021-07-02\"\nrelease_message = \"\"\"\nThis release adds more flexibility for handling side-set extrusion and\ntopography in 2-D, as well as a more robust implementation of processing\nfunction serialization. Additionally, the minimum supported CUDA Compute\nCapability has been lowered to 3.5, and as such Kepler-based NVIDIA GPUs can\nnow be used.\\\n\"\"\"\n\n[[\"0.11.36\".changes]]\nchange_id = \"extrude-side-sets-2d\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a utility to extrude meshes across side sets in 2D.\nThe functionality is currently limited to Cartesian meshes and\nside sets aligned with a coordinate axis.\n\nExample:\n```python\nmesh = basic_mesh.CartesianHomogeneousAcoustic2D(\n    vp=1500.0, rho=1000.0, x_max=1.0, y_max=0.5,\n    max_frequency=1e3,\n).create_mesh()\n\nmesh = mesh.extrude_side_set_2D(\n    side_set=\"x1\",\n    offsets=np.array([0.0, 2.0, 4.0]),\n    direction=\"x\",\n)\n```\\\n\"\"\"\n\n[[\"0.11.36\".changes]]\nchange_id = \"improve-dem-2d\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nMore general definition of 2D dem objects for non-spherical models.\nNow, y0 can be set to `-np.inf` to deform all elements in `y` direction\nwith negative `y` coordinates.\n\nExample:\n```python\nmesh = basic_mesh.CartesianHomogeneousAcoustic2D(\n      vp=1500.0, rho=1000.0, x_max=1.0, y_max=2.0, max_frequency=10e3\n  ).create_mesh()\n  mesh.points[:, 1] -= 0.5\n  mesh.add_dem_2D(\n      x=np.array([0.0, 1.0]),\n      dem=np.array([-0.25, 0.25]),\n      y0=-np.inf,\n      y1=np.inf,\n      kx=1,\n      ky=1,\n  )\n  mesh.apply_dem()\n```\\\n\"\"\"\n\n[[\"0.11.36\".changes]]\nchange_id = \"better-function-serialization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvusProject sometimes has to serialize Python functions to disc (e.g. misfits,\nprocessing functions, ...).\n\nThis now works with more functions, like functions that call other custom\nfunctions, closure values within with statements and a few other things.\n\nIn general it should just be more reliable.\\\n\"\"\"\n\n[[\"0.11.36\".changes]]\nchange_id = \"grid-engine-support\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd initial support for the GridEngine job queueing system.\n\nThere are a number of different versions of GridEngine out there and minor\nadjustments might be necessary for Salvus to run on them. Please let us know if\nyou encounter some.\\\n\"\"\"\n\n[[\"0.11.36\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nUpgrade to PETSc 3.15.1.\\\n\"\"\"\n\n[[\"0.11.36\".changes]]\nchange_id = \"support-cuda-cc-35-and-greater\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nPreviously, the lowest CUDA compute capability supported by Salvus was 6.0, due\nto the unavailability of a double precision atomic add function in previous CCs.\nA workaround is now implemented, which should allow Salvus to run on GPUs of CC\n3.5 and greater. Note that NVIDIA will soon deprecate architectures < 6.0, so at\nsome point in the future new Salvus versions will again only support CC 6.0 and\ngreater.\\\n\"\"\"\n\n[\"0.11.35\"]\nrelease_date = \"2021-06-23\"\nrelease_message = \"\"\"\nMinor update including small bug fixes and adding support for constant\nmaterial parameters per element.\\\n\"\"\"\n\n[[\"0.11.35\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSmall improvements in the CI and better handling of MR pipelines.\\\n\"\"\"\n\n[[\"0.11.35\".changes]]\nchange_id = \"bug-fix-viz-2d-box-domain\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSmall bug fix to visualize 2D box domains without receivers.\\\n\"\"\"\n\n[[\"0.11.35\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpgrade to mypy 0.902 by installing type stub helper packages.\\\n\"\"\"\n\n[[\"0.11.35\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nAllow elemental fields to be read in by the solver. To use this feature, pass a\nfield that is explicitly of shape (nelem, 1) -- i.e. the \"1\" in the trailing\ndimension is explicitly specified.\\\n\"\"\"\n\n[[\"0.11.35\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nRewriting structured grid with respect to license agreement.\\\n\"\"\"\n\n[\"0.11.34\"]\nrelease_date = \"2021-05-28\"\nrelease_message = \"\"\"\nThis release comes with several small fixes and improvements listed below.\n\nNew features include built-in support for two new source time functions,\nbox constraints for inverse problems.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"more-flexible-absorbing-boundaries\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nA list of side sets can now be passed to the `free_surface` argument of\n`AbsorbingBoundaryParameters`. These side sets will in turn not be extended with\nabsorbing layers (if they are requested), and no absorbing conditions will be\nplaced on them. This is useful, for instance, to model a thing plate\n(`free_surface=[\"z0\", \"z1\"]`).\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"add-new-source-time-functions\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds two useful built-in source-time functions: a Tone Burst, commonly used to\nmodel ultrasound transducers, and a wavelet with a flattened spectrum, sometimes\nused in geophysical applications.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"receiver-collection-to-list\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds a `.to_list()` function to all receiver collections so that multiple\ncollections can more easily be appended to each other.\\\n\"\"\"\n\n\n[[\"0.11.34\".changes]]\nchange_id = \"add-toggle-mesh-button\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe Jupyter notebook mesh visualization widget now has a \"Toggle Mesh\" button to\nquickly toggle the visibility of the mesh. This is to look at sources and\nreceivers inside the mesh.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"interpolation-coordinate-axes\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nIn some rare cases the order of the coordinates in xarray data sets was not\npassed on correctly to Salvus' internal interpolation routines. This now works\nas expected.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"paramiko-stdin-cleanup\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nMitigate an error that sometimes happened upon closing the paramiko SSH and SFTP\nclients.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"error-message-mpich\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nMPICH sometimes causes a problem on OSX. If this happens during site\ninitialization the error message now points to the section on the Mondaic\nwebsite that describes how to solve it.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"receiver-placement-more-stable\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe source and receiver placement could previously fail for strongly distorted\nhigh-order elements. For these rare cases it now falls back to a slower, more\nbrute-force method that should always work.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"improve-temporal-resampling-stf\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nImproved the temporal resampling of custom STF functions which is useful for\nplotting on the Python side.\\\n\"\"\"\n\n\n[[\"0.11.34\".changes]]\nchange_id = \"delete-dependent-meshes\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nDeleting a volume, topography, or bathymetry model will now delete any\ndependent, auto-generated meshes.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"compat-with-pyproj-3-1\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nMake SalvusProject compatible with the latest pyproj 3.1.0 package.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"new-gradient-output-formats\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded new gradient output formats `hdf5-full` and `hdf5-minimal`.\n`hdf5-full` contains additional fields stored in the input mesh, e.g., the\nindex of layers / regions. `hdf5-minimal` will only write the data fields of\nthe gradient, but neither coordinates, connectivity nor an xdmf file.\n\nThe default format `hdf5` remains unchanged.\\\n\"\"\"\n\n[[\"0.11.34\".changes]]\nchange_id = \"box-constraints\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd optional box constraints to the InverseProblemConfiguration and implement\nthe related projection algorithm for the trust region method.\n\nHere is a snippet that adds lower and upper bounds on VP to an inversion:\n\n```python\nmesh = p.simulations.get_mesh(\"initial_model\")\nlb = mesh.copy()\nlb.elemental_fields[\"VP\"] *= 0.8\nlb.elemental_fields[\"RHO\"] *= 0.8\n\nub = mesh.copy()\nub.elemental_fields[\"VP\"] *= 1.2\nub.elemental_fields[\"RHO\"] *= 1.2\n\np.inversions.set_constraints(\n    inverse_problem_configuration=\"my_third_inversion\",\n    constraints={\n        \"lower_bounds\": lb,\n        \"upper_bounds\": ub,\n    },\n)\n```\\\n\"\"\"\n\n[\"0.11.33\"]\nrelease_date = \"2021-05-11\"\nrelease_message = \"\"\"\nThis release makes sure Salvus keeps working with the latest versions of\n`xarray` and `SQLAlchemy`. A consequence of this is that the Python `netCDF4`\npackage is now a hard dependency.\n\n**Please make sure your conda environment/Python installation is up-to-date\nbefore upgrading to this Salvus version.**\n\n[Click here for upgrade instructions.](https://docs.mondaic.com/updates)\n\nAdditionally this release adds the option to invert for homogeneous material\nparameters in the full waveform inversion workflow.\\\n\"\"\"\n\n[[\"0.11.33\".changes]]\nchange_id = \"compatibility\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nUpdates to make it work with the latest versions of `xarray` and `SQLAlchemy`.\nThe `netCDF4` package is now a hard dependency which should improve\ncompatibility when reading and writing files with `xarray`.\\\n\"\"\"\n\n[[\"0.11.33\".changes]]\nchange_id = \"ask-for-gpus\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `salvus-flow add-site` wizard will now also ask if it should\nrun Salvus using GPUs on a newly configured site.\\\n\"\"\"\n\n[[\"0.11.33\".changes]]\nchange_id = \"fix-add-site\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the `SiteNameValidator` that caused `add-site`\nto crash when no other site has been initialized yet.\\\n\"\"\"\n\n[[\"0.11.33\".changes]]\nchange_id = \"homogeneous-model-inversion\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nExtend the mapping function to support inversion for homogeneous models.\\\n\"\"\"\n\n\n[\"0.11.32\"]\nrelease_date = \"2021-05-05\"\nrelease_message = \"\"\"\nThis release fixes a few minor bugs relevant for regular-grid model extraction,\nmesh-to-mesh interpolation, and database management.\\\n\"\"\"\n\n[[\"0.11.32\".changes]]\nchange_id = \"fix-type-issue-match-layers\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a type issue within `salvus_mesh_utils._match_layers` that could\ncrop up if a mesh was generated outside of SalvusProject.\\\n\"\"\"\n\n[[\"0.11.32\".changes]]\nchange_id = \"fix-bug-in-get-enclosing-elements\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixes a bug where, in certain exceptional cases, `get_enclosing_elements` would\nnot return the proper reference coordinates.\\\n\"\"\"\n\n[[\"0.11.32\".changes]]\nchange_id = \"error-message-db-corruption\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvus now raises an actionable error message in case the internal SQLite\ndatabase got corrupted or does not work for another reason.\\\n\"\"\"\n\n[\"0.11.31\"]\nrelease_date = \"2021-04-23\"\nrelease_message = \"\"\"\nThis release comes with a new experimental feature for general mesh-to-mesh\ninterpolations, which is very useful to interpolate the same model between\nto different discretizations.\n\nAdditionally, we added a workaround for a bug in parallel HDF5 that\nsometime occured when reading or writing large datasets.\\\n\"\"\"\n\n[[\"0.11.31\".changes]]\nchange_id = \"mesh-to-mesh-interpolation\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nGeneric mesh-to-mesh interpolation is now implemented in 2- and 3-D! This is\nuseful in several situations, such as\n\n* representing two models on the exact same mesh,\n* increasing the frequency band in an ongoing inversion, and\n* re-meshing a model due to a decrease in minimum velocity,\n\namong others. The primary interpolation function is available in\n`salvus.mesh.tools.transforms`. Along with full-mesh interpolations,\nlayer-to-layer discontinuity-preserving interpolations, and \"flattened\"\ninterpolations handling topographic deformations, are supported. Additional\nhelper functions for re-meshing applications have also been added to\n`salvus.mesh.salvus_mesh_utils`. One of theses is a function to extract\na conservative 1-D model from an unstructured mesh, which helps to ensure that\na new mesh can be generated that respects both the 3-D minimum velocities and\nexisting discontinuities. Another is a function to match up layers between\ntwo unstructured meshes in the case that their IDs are different. This is\nhelpful in the case where the interpolation should respect pre-defined\ndiscontinuities in the model.\n\nThe method currently does not raise if the spatial domains covered by the\ntarget mesh is contained in the source mesh. Use this with care.\n\nFor additional information, please see our new tutorial on mesh-to-mesh\ninterpolations.\\\n\"\"\"\n\n[[\"0.11.31\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nClarify in the docstring that `UnstructuredMesh.write_binary_vtk()` does not\nwrite the material parameters.\\\n\"\"\"\n\n[[\"0.11.31\".changes]]\nchange_id = \"workaround-for-large-hdf5-dataset-write\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThere still seems to be an issue with parallel HDF5 and writing large amounts\nof data per rank in HDF5 1.12.0. This patch implements a workaround for\nexecution on a single rank.\\\n\"\"\"\n\n\n[\"0.11.30\"]\nrelease_date = \"2021-04-14\"\nrelease_message = \"\"\"\nThis release comes with two main features: (1) better support for spherical\nchunk domains formed by arbitrary polygons and (2) a new output format to\ncompute the wavefield in frequency domain for a set of specified frequencies\nby applying the Fourier transform on the fly during the simulation.\n\nAdditionally, there are several important bug fixes related to SmoothieSEM\nmeshes, reading large hdf5 datasets, and writing xdmf files in SalvusCompute.\\\n\"\"\"\n\n[[\"0.11.30\".changes]]\nchange_id = \"fft-on-the-fly\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable on-the-fly Fourier transforms to output the volumetruc wavefield in\nfrequency domain for a list of discrete frequencies.\n\nIt can be configured in the `simple_config.simulation.Waveform` object using\n`output.frequency_domain`.\n\nThis feature is currently only enabled for simulations on CPUs.\\\n\"\"\"\n\n[[\"0.11.30\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nScript autogeneration of template instantiations.\\\n\"\"\"\n\n[[\"0.11.30\".changes]]\nchange_id = \"fix-xdmf-write\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in SalvusCompute that caused multiple ranks to write xdmf files.\\\n\"\"\"\n\n[[\"0.11.30\".changes]]\nchange_id = \"fix-for-smoothiesem-inner-core\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixes an issue that caused broken meshes when smoothiesem was used with high\nnumber of elements in lateral direction.\\\n\"\"\"\n\n[[\"0.11.30\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nA few helper functions for the visco acoustic toy problem.\\\n\"\"\"\n\n[[\"0.11.30\".changes]]\nchange_id = \"workaround-for-large-hdf5-dataset-read\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nIt seems as though the large dataset mitigations introduced in HDF5 1.10.2 were\nonly applied to dataset writes, and not reads. This introduces a temporary\nworkaround to read models with large (> 2GB) amounts of data per rank.\\\n\"\"\"\n\n[[\"0.11.30\".changes]]\nchange_id = \"spherical-chunk-polygon\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nVarious bug fixes and quality-of-life improvements when using a\n`SphericalChunkDomain` together with a spherical polygon to further constrain\nthe spatial extent. Most importantly conversions between WGS84 and fully\nspherical coordinates are now consistent with the rest of Salvus. The\nin-notebook domain plot now also works and shows the original spherical chunk\ntogether with the domain polygon.\\\n\"\"\"\n\n[\"0.11.29\"]\nrelease_date = \"2021-04-06\"\nrelease_message = \"\"\"\nMinor release which fixes a bug in certain GPU runs, and adds the capability to\nlimit the number of simultaneously running jobs in a slurm job array.\\\n\"\"\"\n\n[[\"0.11.29\".changes]]\nchange_id = \"fix-1-rank-per-node-gpu-issue\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug that previously existed where, in the case of a multi-node GPU run\nwith 1 rank per node, the GPU halo would not get initialized properly. This\nwould then lead to a failure during site initialization (as expected).\\\n\"\"\"\n\n[[\"0.11.29\".changes]]\nchange_id = \"slurm-limit-parallel-job-array-runs\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nOptionally limit the number of parallel jobs in a slurm job array.\n\nThis can be specified in the site configuration of a slurm site with\n\n```yaml\nmax_simultaneous_jobs_in_job_array = 4\n```\n\nwhich internally translates to, for example, the `%4` in `--array=0-15%4`.\\\n\"\"\"\n\n[\"0.11.28\"]\nrelease_date = \"2021-03-19\"\nrelease_message = \"\"\"\nMinor release including a few bug fixes listed below. Additionally, the\nspectral-element order and output sampling rate for receivers is now\nconfigurable through the `WaveformSimulationConfiguration`.\\\n\"\"\"\n\n[[\"0.11.28\".changes]]\nchange_id = \"point-output-in-wsc\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the sampling interval for point output to the\nWaveformSimulationConfiguration.\\\n\"\"\"\n\n[[\"0.11.28\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nTiny update to avoid a deprecation warning in `sqlalchemy>=1.4.0`.\\\n\"\"\"\n\n[[\"0.11.28\".changes]]\nchange_id = \"side-sets-for-oceans-on-utm-domains\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug where side-sets involving fluid layers on UTM domains where\nincorrectly attached.\\\n\"\"\"\n\n[[\"0.11.28\".changes]]\nchange_id = \"configurable-order-in-wsc\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe polynomial degree of the spectral-element basis is now configurable\nin the `WaveformSimulationConfiguration`.\n```python\nw = WaveformSimulationConfiguration(spectral_element_order=6)\n```\nIf not specified, the default remains at `4` as in all previous releases.\\\n\"\"\"\n\n[[\"0.11.28\".changes]]\nchange_id = \"dont-fail-on-directory-deletion-failure\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe last part of running a simulation usually is to delete the remote run and\ntemp directories Salvus needs to simulate waves. In most cases this just\nworks but especially on network file systems the file system might be busy\nand refuse to actually delete anything. Previously this resulted in an\nexception but because everything else worked fine this was undesired. It now,\nby default, only raises a warning.\n\nYou can restore the old behaviour by setting `raise_on_deletion_failure=True`\nwhen using the low-level SalvusFlow API calls:\n\n```python\nsn.api.run(..., raise_on_deletion_failure=True)\nsn.api.run_many(..., raise_on_deletion_failure=True)\n```\n\nAs before it will retry deleting a remote directory up to 5 times before\nactually raising the warning or exception with a now slightly increased\ntimeout between retries.\n\nIt will also no longer raise in these cases in SalvusProject which should\nmake it more stable on some file systems.\\\n\"\"\"\n\n[\"0.11.27\"]\nrelease_date = \"2021-03-01\"\nrelease_message = \"\"\"\nThe main feature in this release is a new method for the visualization /\nanalysis of 2- or 3-D models and gradients. The addition of the function\n`extract_model_to_regular_grid` to the `salvus.mesh.salvus_mesh_utils`\nmodule allows users to regularly sample a given mesh given locations\nspecified by an `xarray` dataset. Additional improvements include a more\nflexible API for surface topography in UTM domains, a memory use mitigation\nwhen running many shots with the same mesh, and the automatic up-casting of\nrelated types in certain schema (for example: \"2 elements per wavelength\" is\nnow upcast to \"2.0 elements per wavelength\").\\\n\"\"\"\n\n[[\"0.11.27\".changes]]\nchange_id = \"extract-mesh-to-regular-grid\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nA new function named `extract_model_to_regular_grid` has been added to the\n`salvus_mesh_utils` module. This function performs an interpolation from a\ngeneral, unstructured mesh (spherical or cartesian) to a set of points defined\non a `xarray` dataset. This can be useful, for instance, to create slices\nthrough a model for efficient visualization and analysis. See the function's\ndocstring for additional examples, information, and tips.\\\n\"\"\"\n\n[[\"0.11.27\".changes]]\nchange_id = \"allow-no-deformation-above-for-utm-topography\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nA new parameter can optionally be passed to a cartesian `SurfaceTopography`\nobject that restricts the mesh deformation above a given z-value. This is\nuseful, for instance, when placing a layer (i.e. the atmosphere) above a free\nsurface with topography. Related constructors (such as\n`SurfaceTopography.from_gmrt_file()` optionally take this parameter as well.\\\n\"\"\"\n\n[[\"0.11.27\".changes]]\nchange_id = \"autocast-int-to-float\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAutomatically cast integers to floats in many cases where objects expect\nfloating point values to be set.\\\n\"\"\"\n\n[[\"0.11.27\".changes]]\nchange_id = \"simulation-objects-copy\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nCopying simulation objects now, by default, only references a potentially\nattached mesh.\n\nMany workflow have a large number of copied simulation objects which can\nresult in a high memory usage if the meshes are copied as well.\n\nThe meshes can still be optionally copied with:\n\n```python\nw_copy = w.copy(copy_mesh=True)\n```\\\n\"\"\"\n\n[[\"0.11.27\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nRemoved the warning filter for arrow < 0.15. This resulted in some very\nstrange import error with arrow >= 1.0.0 that I don't understand. But\nremoving the `arrow.factory` import gets rid of the error so maybe good\nenough for now?\\\n\"\"\"\n\n[\"0.11.26\"]\nrelease_date = \"2021-02-23\"\nrelease_message = \"\"\"\nThis release focusses on quality of life improvements for solving the inverse\nproblem. It includes a bunch of bug fixes as well as new features.\n\nA new tab has been added to the inversion dashboard showing some\ndetails about model updates and the evolution of the trust-region algorithm.\nThis grants insights into how an ongoing inversion is doing.\n\nSalvusProject and SalvusFlow can now recover more gracefully from partially\nfailed job arrays where only a few jobs did not finish.\n\nFurthermore the window picking for seismological full waveform inversions is\nnow a lot faster.\n\nNote that plotly >= 4.12.0 is required to display the new widgets properly.\nTo update the python environment, check the installation instructions or run\n\n```bash\nwget https://mondaic.com/environment.yml -O salvus-0.11.26.yml\nconda env update -n salvus -f salvus-0.11.26.yml\n```\n.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nchange_id = \"fix-gradient-widget\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nBug fix for the gradient widget of the inversion dashboard, where previously\nsome event-dependent gradients were not displayed correctly.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nchange_id = \"fix-extra-output-configuration\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nBug fix in the SimulationConfiguration to ensure the\n`extra_output_configuration` passed to `launch` overwrites additional output\nvalues defined in the `WaveformSimulationConfiguration`. The output options\nin the `WaveformSimulationConfiguration` will be deprecated in a future\nrelease.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nchange_id = \"trust-region-steering-parameters\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nExpose more parameters to steer the adaptive adjustment of the\ntrust-region radius.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nchange_id = \"trust-region-visualization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new tab to the inversion dashboard to visualize the progress of\nmodel updates and trust-region radius.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nchange_id = \"improve-misfit-visualization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a toggle button to the misfit widget to switch between absolute and\nrelative misfits - normalized per iteration or event, respectively.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nchange_id = \"better-window-picking\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nMuch faster seismological window picking for some cases. Additionally it is\nnow a bit more conservative and will not pick some sketchy windows it did not\npick before. All in all the picked windows should be very similar to results\nfrom the previous version of this algorithm but a few less windows will be\npicked.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nRemoved obsolete now obsolete load leveller file.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nchange_id = \"has-data-for-synthetics\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `p.waveforms.has_data()` method now also works for synthetic data.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nchange_id = \"partial-recovery-salvus-flow\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nIf a few jobs in a Salvus job array failed for some reason, the output for\nthe successfully completed jobs can now be retrieved in a much simpler way:\n\n```\nSalvusJobArray.copy_output(..., copy_partial_results=True)\n```\n\n`copy_partial_results` defaults to `True`.\n\nThe same parameter is exposed to the `salvus.flow.functions.run_many()` command\nand also defaults to `True` there.\\\n\"\"\"\n\n[[\"0.11.26\".changes]]\nchange_id = \"partial-recovery-salvus-project\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe partial copy of the Salvus job array results has been integrated into all\nparts of SalvusProject. If one or more jobs fail for a forward or an adjoint\nsimulation, it will still raise an exception but copy all successfully\ncompleted jobs to the project folder. Any subsequent simulations launched\nwill be aware of this and not submit the already run ones.\n\nThis makes it much easier to recover from sporadic cluster failures without\nhaving to directly modify the project directory.\\\n\"\"\"\n\n[\"0.11.25\"]\n\nrelease_date = \"2021-02-12\"\nrelease_message = \"\"\"\nThis release comes with several improvements to make inversions run\nmore efficiently. New options to manage checkpoints and to reduce the\nI/O overhead of smoothing have been added. Furthermore, the mapping function\nnow offers more general parameterizations.\n\nAdditionally, some visualization tools have been improved,\nand a tuning parameter to mesh ocean layers was added.\n\nFinally, Salvus now by default supports GLL orders of 1-7.\nAdditional orders remain available upon request.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nchange_id = \"memory-settings-in-siteconfig\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd `memory_per_rank_in_MB` as optional parameter to `SiteConfig`.\nThis allows to adjust the memory settings for different machines\nduring an inversion.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nchange_id = \"flexible-parameterizations-in-mapping\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd support for flexible parameter mappings and inversion for\nrelative or absolute perturbations:\n\n\n```python\nsn.Mapping(\n      scaling=\"relative_deviation_from_prior\",\n      inversion_parameters=[\"VSV\", \"VSH\", \"VP\", \"RHO\"],\n      map_to_physical_parameters={\n          \"VPV\": \"VP\",\n          \"VPH\": \"VP\",\n      }\n  )\n```\nThe example above assumes a prior model parameterized as\nTTI medium. It inverts for four independent parameters that\nencode relative perturbations from the prior model.\nThe deviations in `VPV` and `VPH` are tied to the same\ninversion variable `VP`.\\\n.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nchange_id = \"reduce-mesh-io-in-smoothing\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nReduce the file access of the smoothing algorithms to construct\nthe diffusion models and enable remote diffusion meshes.\\\n\"\"\"\n\n\n[[\"0.11.25\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpgrade min. ujson requirement to 4.0.2.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nchange_id = \"compile-multiple-orders\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSEM orders 1-7 are now supported by default for simulation.\nAdjoint simulations on GPUs are currently limited to order 4.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix CUDA tests in the CI, where many were accidentally skipped.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nchange_id = \"checkpoint-handling\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove memory management of checkpoints in SalvusProject.\n\nThis gives more flexibility to tune the strategy regarding checkpoints.\nBy default, checkpoints will be stored for every forward run, and\nautomatically removed after (a) gradients for the simulation configuration\nhave been computed and/or (b) the model got rejected by the trust region\nalgorithm.\n\nThis behavior can be modified using optional boolean flags `store_checkpoints`\n and  `cleanup_checkpoints` in the `job_submission` settings.\n\n```python\njob_submission={\n  \"forward\": ...,\n  \"preconditioner\": ...,\n  \"store_checkpoints\": False,\n  \"cleanup_checkpoints\": False,\n}\n```\n\nIf the former is\n`False` checkpoints will only be stored when gradients are requested. If the latter\nis `False` checkpoints will never be deleted automatically.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate type hints so it still passes with mypy 0.8. Mainly means quite a few things\nare now type hinted that previously were not.\nAlso works for the /conf folder.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nIgnore a few deprecation warnings for numpy 1.20.0. All of them are raised by\nsome upstream dependency.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nSend the Salvus version number in the license request.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAbility to display custom server-side release messages in the new salvus\nversion prompt.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nchange_id = \"ocean-lateral-element-size\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdding a new parameter to better control the lateral element size in the ocean.\nThis is particularly relevant for local domains with strong bathymetry, where\nSnel's law in 1D may break down.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nChange default for shore smoothing to 0 for better stability.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nChunked constructor for Cartesian2DHomogeneous and Cartesian3DHomogeneous,\nbetter location for heavy temp files.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nchange_id = \"output-src-rec-locations-as-vtk\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nIt is sometimes convenient to visualize source and receiver locations in\nParaview. A new function, `salvus.flow.utils.simulation_src_rec_to_vtk`, has\nbeen added to facilitate this. As arguments it takes a `simulation.Waveform`\nobject, along with a string specifying what type of entity one wants to\ngenerate a `.vtk` file for (i.e. source or receiver). Check the function's\ndocstring for advice on how to open the resultant file in Paraview.\\\n\"\"\"\n\n[[\"0.11.25\".changes]]\nchange_id = \"optionally-exclude-colorbar-from-shotgathers\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `_plot` method of an `EventData` object now takes an additional optional\nparameter: `_exclude_cbar`. If set to true, a colorbar won't be added to the\naxis if a shotgather plot is requested. This makes it easier to produce\nshotgathers for multi-component data (i.e. for strain output).\\\n\"\"\"\n\n\n[\"0.11.24\"]\n\nrelease_date = \"2021-01-12\"\nrelease_message = \"\"\"\nThis release comes with a couple of generalizations and bug fixes related\nto preconditioners of the inverse problem as well as utilities to deal with\ncylindrical meshes.\\\n\"\"\"\n\n[[\"0.11.24\".changes]]\nchange_id = \"cylindrical-meshes\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd utilities to create cylindrical meshes including side sets and\ntopography.\\\n\"\"\"\n\n[[\"0.11.24\".changes]]\nchange_id = \"additional-cartesian-3d-receiver-collections\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nNew receiver collections to facilitate the creation of 3D apertures\non Cartesian domains.\\\n\"\"\"\n\n[[\"0.11.24\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nUpdate copyright statement to 2021 in all source files.\\\n\"\"\"\n\n[[\"0.11.24\".changes]]\nchange_id = \"space-dependent-smoothing-preconditioner\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable space-dependent smoothing with arbitrary (an)-isotropic\nsmoothing lengths as preconditioner of an InverseProblemConfiguration.\\\n\"\"\"\n\n[[\"0.11.24\".changes]]\nchange_id = \"fix-auto-timestep-detection\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the auto time-step detection of the diffusion and the\nanisotropic acoustic wave equation that could previously result in a\nsignificant under-estimation of a stable time-step size.\\\n\"\"\"\n\n[[\"0.11.24\".changes]]\nchange_id = \"fix-gradient-plotting\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in plotting gradients in the inversion dashboard or using\n`p.viz.nb.gradients`.\\\n\"\"\"\n\n\n[\"0.11.23\"]\n\nrelease_date = \"2020-12-03\"\nrelease_message = \"\"\"\nThis release adds several quality-of-life improvements for ongoing\ninversions, as well as a more sophisticated scheme to handle sites where two\nfactor authentication is required. Support for volumetric models in 2-D\nseismological domains was added, along with a relevant tutorial (\"Teleseismic\n2D\"). Volumetric seismological mantle and crustal models will also now\nautomatically recognize the presence of oceans, and restrict the\ninterpolation of material parameters to the elastic regions. If more control\nover this process is desired, one can still use the `GenericModel`\nconstructor.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nchange_id = \"stopping-criteria-for-inverse-problem\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable stopping criteria to limit the maximum number of iterations in an\ninverse problem. This is mainly useful for automated monolithic inversion\nworkflows.\n\n```python\np.inversions.set_stopping_criteria(\n  inverse_problem_configuration=\"...\",\n  criteria={\n    \"max_iterations_global\": 10,\n    \"max_iterations\": 5,\n  }\n)\n```\nThe criteria can be overwritten anytime to continue with the inversion.\n`global` settings apply to the entire inversion tree, the other settings\napply to individual branches.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nchange_id = \"allow-project-relocation-with-inverse-problems\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nRemove some path dependencies which previously prevented renaming the project.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nchange_id = \"ssh-port\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe port number of remote sites in the `~/.ssh/config` file is now respected.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nchange_id = \"interactive-login\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvus can now perform interactive SSH logins. This is necessary for example\nfor interactive two factor authentication schemes.\n\nEnable it like this in the site configuration:\n\n```toml\n        [sites.site_name.ssh_settings]\n            hostname = \"host\"\n            username = \"user\"\n            interactive_login = true\n```\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nchange_id = \"2d-seismo-domain-improvements\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nVarious improvements to make 2-D seismological domains more useful.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFixing the chunked output files.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nBug fix for tidal load interpolation.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nchange_id = \"chunkwise-meshing\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdds functionality to refine, increase tensor order or build meshes in chunks\nto avoid memory bottlenecks. In particular, this adds two new functions:\n\nFirstly, in `salvus.mesh.tools.transforms` `uniformly_refine_chunkwise()`\nwraps `uniformly_refine()` working with a subset of elements at a time,\nwriting each of the readily processed chunks to a temporary file and finally\nmerging everything together. This can both be used to refine each element by\nsubdivision into an arbitrary number of elements in each dimension and/or to\nincrease the order of the shape mapping.\n\nSecondly, `salvus.mesh.chunked_interface.create_mesh_chunkwise()` can be used\ninstead of `create_mesh()` of `SphericalChunk3D`, `Cartesian3D` and\n`Cartesian2D` using the same approach as described above to directly create\nlarge meshes that would otherwise reach the memory limitations of the\nmachine.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nBetter error messages.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nFix anisotropic refinements for tidal loading.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nThere was an issue with the type of the layer array in a slice, not sure how\nit was working before. Just adds an explicit typecast to fix it up.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nchange_id = \"allow-for-2d-seismological-volumetric-models\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe interpolation of volumetric models onto seismological meshes was\npreviously only available for 3-D domains. Support is now extended to 2-D\ndomains, with \"longitude\" and \"radius\" OR \"depth\" being required coordinate\naxes in the parent xarray Dataset. A new tutorial (`teleseismic_2d`) has been\nadded, fleshing out this feature.\\\n\"\"\"\n\n[[\"0.11.23\".changes]]\nchange_id = \"restrict-interpolation-for-seismological-models\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd the ability to ignore elements flagged with a certain value during volume\nmodel interpolation for seismological models. This is useful, for instance,\nif one wants to limit interpolation to a specific region (say, the elastic\nsubsurface, and not any water layers). See the description in the seismology\n`GenericModel` constructor for more details. Crustal and Mantle models will\nnow ignore fluid elements by default, to ensure that elastic models are not\ninterpolated into oceans. Is this behavior is undesirable, one has more\ncontrol with the `GenericModel` interface.\\\n\"\"\"\n\n[\"0.11.22\"]\n\nrelease_date = \"2020-11-10\"\nrelease_message = \"\"\"\nThis release contains several small improvements to streamline the workflow\norchestration behind the scenes.\\\n\"\"\"\n\n[[\"0.11.22\".changes]]\nchange_id = \"better-adjoint-workflow\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nProvide a workaround for externally computed and incorrect adjoint sources.\nIt is strongly recommend to verify the implementation of custom misfits and\nadjoint sources with a finite-difference test.\nUsing the optional parameter `force_trust_region_scaling` badly scaled\nadjont sources can be mitigated by enforcing to scale the proposed model\nupdate to the trust region radius.\\\n\"\"\"\n\n[[\"0.11.22\".changes]]\nchange_id = \"improved-strategy-to-download-data\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nWhen re-launching simulations for which data already exist\n(e.g. to compute checkpoints), previously computed outputs are kept in the\nproject file structure and only overwritten once the new jobs have finished.\nAdditionally, a utility to manually clean the simulation store has been added.\\\n\"\"\"\n\n[[\"0.11.22\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nForce a min pythreejs version of 2.2.1 which solves the traitlet problem.\\\n\"\"\"\n\n[[\"0.11.22\".changes]]\nchange_id = \"database-maintenance\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nSalvus uses a job database to keep track of asynchronously launched jobs.\nOver time this database can become quite big to the point of negatively\neffecting the total performance.\n\nWith this change Salvus will now perform periodic maintenance of the database\nto optimize it and keep its size in check.\n\nAdditionally finished jobs are no longer moved into the \"archived\" group in\nthe database but removed from the database upon job deletion. We don't expect\nthis to have an effect on any user.\\\n\"\"\"\n\n[[\"0.11.22\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nNow works with h5py 2.x.x and 3.x.x\\\n\"\"\"\n\n\n[\"0.11.21\"]\n\nrelease_date = \"2020-11-05\"\nrelease_message = \"\"\"\nThis release contains several quality of life improvements and fixes for some\nminor issues.\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nchange_id = \"better-adjoint-workflow\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe internal workflow for handling checkpoints and adjoint simulations has\nbeen improved to avoid duplicated simulations for missing checkpoints on\nremote sites. This changes the hash values of adjoint simulations, which do\nnot depend on synthetic receiver files anymore.\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nchange_id = \"python-binary-in-flow-config\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe site configuration for local and SSH sites now has an extra\n`python_binary` key to choose which Python is used to execute the minimal\nwrapper script used to launch and control SalvusCompute. This is only\nimportant for sites which do not have a Python on their default paths.\n\nUsage:\n\n```toml\n  [sites.laptop]\n    ...\n    [sites.laptop.site_specific]\n    python_executable = \"/usr/local/bin/python\"\n```\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nForce a min paramiko version of 2.7.2.\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nThe version logic now no longer picks up git repositories that are not the\nSalvus repository. This fixes an obscure bug when the Python site-packages\ndirectory is a git repository.\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nchange_id = \"username-with-proxyjump\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSalvus now supports usernames in SSH proxy jump connections with settings like\n`ProxyJump user@hostname` in `~/.ssh/config` files.\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nchange_id = \"windows-without-absolute-times\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe waveform plotting widget can now also plot windows without a reference\ntime.\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nchange_id = \"db-disc-full\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nA full disk previously raised an error that the internal Salvus*Flow*\ndatabase was corrupt. It now gives a more descriptive error message.\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nchange_id = \"init-site-warn-disk-usage\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\n`salvus-flow init-site SITE_NAME` now always prints the disk usage of the\nSalvus controlled run and temp directories. As `init-site` is called each\ntime Salvus is upgraded this serves as a period reminder to monitor the size\nof these directories.\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAlgorithmic improvements in the local refinements to speed up smoothiesem.\\\n\"\"\"\n\n[[\"0.11.21\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAllowing single element inner cores in 2D and 3D.\\\n\"\"\"\n\n[\"0.11.20\"]\n\nrelease_date = \"2020-10-25\"\nrelease_message = \"\"\"\nThis release brings in local refinements for cylindrical meshes, a speed-up\nfor surface data output, and several usability improvements in SalvusProject.\nSee below for a detailed list of features and bugs that have been patched.\\\n\"\"\"\n\n[[\"0.11.20\".changes]]\nchange_id = \"extra-output-in-project-simulations\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `p.simulations.launch()` method can now take extra output configurations.\nThese can be any setting that does not modify the receiver output which\ncurrently are surface and volume data settings as well as the memory per rank\nbuffer settings.\n\n```python\np.simulations.launch(\n    simulation_configuration=\"basic\",\n    events=p.events.list(),\n    site_name=\"my_computer\",\n    ranks_per_job=12,\n    extra_output_configuration={\n        \"volume_data\": {\n            \"sampling_interval_in_time_steps\": 50,\n            \"fields\": [\"displacement\"],\n        },\n        \"surface_data\": {\n            \"sampling_interval_in_time_steps\": 20,\n            \"fields\": [\"acceleration\", \"velocity\"],\n            \"side_sets\": [\"x0\", \"x1\"],\n        },\n        \"memory_per_rank_in_MB\": 2000.0,\n    },\n)\n```\\\n\"\"\"\n\n\n[[\"0.11.20\".changes]]\nchange_id = \"local-refinement-cylindrical\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nAdd cylindrical interpolation to local refinement schemes and adopt same\ninterface as change_tensor_order() has for interpolation_type. This changes the\napi for spherical interpolation from\n\n```python\nm.refine_locally(mask, spherical=True, r0_spherical=1.0, r1_spherical=2.0)\n```\n\nto\n\n```python\nm.refine_locally(\n    mask,\n\tinterpolation_mode=\"spherical\",\n\tinterpolation_kwargs={\"r0_spherical\": 1.0, \"r1_spherical\": 2.0}\n)\n```\n\nThe new cylindrical scheme can be used accordingly\n\n```python\nm.refine_locally(\n    mask,\n\tinterpolation_mode=\"cylindrical\",\n\tinterpolation_kwargs={\"r0_cylindrical\": 1.0, \"r1_cylindrical\": 2.0}\n)\n```\n\nBelow an example of how this can be used for improved representation of\ncylindrical structures (left new, right old).\\\n\"\"\"\n\n[[\"0.11.20\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nAdding specific refinement templates for SmoothieSEM that may improve the\nmaximum stable time step for high frequency simulations.\\\n\"\"\"\n\n\n[[\"0.11.20\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nAllow Q parameters to be interpolated onto a cartesian volume model,\nregardless of whether or not they are in the background model. A bit of\nunfortunate special-casing, but we currently don't have a good way of\ndistinguishing models with and without Q (a historical issue).\\\n\"\"\"\n\n[[\"0.11.20\".changes]]\nchange_id = \"add-load-if-exists-option-to-project-constructor\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `Project.from_domain()` constructor now takes an optional argument\n`load_if_exists` which defaults to `False`. If this is set to `True`, and if\nthe domains are identical, future runs of this constructor will simply load\nthe existing project from disk rather than raising a \"project already exists\"\nerror. This helps remove some boilerplate code which the user previously had\nto write.\\\n\"\"\"\n\n[[\"0.11.20\".changes]]\nchange_id = \"fix-dirichlet-bug-on-gpu\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixed the applications of pressure-free boundaries for GPU simulations in\ncertain situations where refinements were present along fluid/solid coupling\ninterfaces.\\\n\"\"\"\n\n[[\"0.11.20\".changes]]\nchange_id = \"speedup-facet-detection-for-side-set-output\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSignificant speedup to the detection of which facets to select for surface\noutput.\\\n\"\"\"\n\n[[\"0.11.20\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nSmall updates to ensure compatibility with mypy v0.790 and ujson>4.0.0.\nThis does not fix issue #474(!).\\\n\"\"\"\n\n[[\"0.11.20\".changes]]\nchange_id = \"improve-widgets\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd widget to query status of simulations and and improve the widgets of\nwaveforms and inversions.\\\n\"\"\"\n\n[[\"0.11.20\".changes]]\nchange_id = \"branch-based-widget-view\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nImprove the inversion tree widget to visualize per-branch progress.\\\n\"\"\"\n\n[[\"0.11.20\".changes]]\nchange_id = \"bug-fix-domain-viz\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nMinor bug fix in visualizing 2D domains using `p.viz.nb.domain` that did not\ndisplay some source types correctly.\\\n\"\"\"\n\n\n[\"0.11.19\"]\n\nrelease_date = \"2020-10-05\"\nrelease_message = \"\"\"\nMinor update that enables license tokens for the diffusion equation.\nFurthermore, it adds some utilities to handle remote data in SalvusProject\nas well as small bug fixes listed below.\\\n\"\"\"\n\n[[\"0.11.19\".changes]]\nchange_id = \"pass-linear-solids-to-model-config\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nPrevious to this change, the parameters governing the behavior of the linear\nsolids in viscous simulations would only be properly attached if they came in\nvia a background model. Now these parameters can be supplied to a\n`ModelConfiguration` via the `LinearSolids` class (which can be found in\n`salvus.namespace`). Additional validations and checks have also been added\nto help the user when viscous simulations are either requested or thought to\nbe desired.\\\n\"\"\"\n\n[[\"0.11.19\".changes]]\nchange_id = \"anisotropic-refinement-in-single-layer\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFixing a bug where an anisotropic refinement is used in a single layer spherical model.\\\n\"\"\"\n\n[[\"0.11.19\".changes]]\nchange_id = \"auto-cleanup-checkpoints\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAutomatically clean-up checkpoint files after an adjoint simulation.\\\n\"\"\"\n\n[[\"0.11.19\".changes]]\nchange_id = \"remote-file-handling-utilities\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd utilities to handle remote output data and to manually delete jobs\nin SalvusProject.\\\n\"\"\"\n\n[[\"0.11.19\".changes]]\nproduct = \"SalvusOpt\"\npublic_change = false\ndescription = \"\"\"\nEnable license tokens for simulating the diffusion equation.\\\n\"\"\"\n\n[[\"0.11.19\".changes]]\nchange_id = \"processing-function-chaining\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nChaining processing function in Salvus*Project* now works as expected.\\\n\"\"\"\n\n\n[\"0.11.18\"]\n\nrelease_date = \"2020-09-29\"\nrelease_message = \"\"\"\nMinor update with a couple of bug fixes listed below as well as\nimproved compatibility with `xarray > 0.16.0`.\\\n\"\"\"\n\n\n[[\"0.11.18\".changes]]\nchange_id = \"fix-mesh-from-2d-splines\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug in the horizontal spacing when generating 2D layered meshes from\nsplines and extruding horizontally for absorbing boundaries.\\\n\"\"\"\n\n[[\"0.11.18\".changes]]\nchange_id = \"fix-tf-plot-caption\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFix the description in the caption of time-frequency phase shift plots.\\\n\"\"\"\n\n[[\"0.11.18\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nAttempt to delete the `SUCCESS` again during `RemoteIOExecutor.remote_rmdir()` in\ncase it failed to delete the first time. Otherwise still do a manual\n`rm -rf ...` and raise the old warning.\\\n\"\"\"\n\n[[\"0.11.18\".changes]]\nproduct = \"SalvusOpt\"\npublic_change = false\ndescription = \"\"\"\nAll misfits are now tested to not be dependent on the sampling rate. There is\na test running on all misfits that compares the misfit value for the same\nsignal sampled differently. The misfits should all be the same.\\\n\"\"\"\n\n[[\"0.11.18\".changes]]\nchange_id = \"request-ww-for-components-that-dont-have-it\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFixed a bug where in some specific cases it might have requested windows and\nweights for components that do not have synthetic data and thus failed.\\\n\"\"\"\n\n[[\"0.11.18\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdapted to the changed `.copy()` behavior of xarray 0.16.0 and 0.16.1.\\\n\"\"\"\n\n\n[[\"0.11.18\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nIn UnstructuredMesh.write_h5() with mode='all' store the full high order\nconnectivity to speedup re-reading the mesh with UnstructuredMesh.from_h5().\\\n\"\"\"\n\n\n[\"0.11.17\"]\n\nrelease_date = \"2020-09-18\"\nrelease_message = \"\"\"\nThis release contains improvements in a number of different areas.\n\nSalvus can now compute consistent adjoint sources for measurements on the\ntime derivative fields, e.g. adjoint sources for receivers recording\n`velocity` and `phi_t`. Additionally the (time frequency) phase misfits have\nseen some significant improvements and added flexibility.\n\nOn the model building side there is a new function to derive a 1-D background\nmodel required for meshing from 2- or 3-D Cartesian volumen models.\n\nAside from that there are a few minor additions and bugfixes, please refer to\nthe full changelog for details.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nchange_id = \"cartesian-side-set-array-point3d\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a new Cartesian receiver collection which creates a 2-D array of side set\nreceivers for use with 3-D models. The presence of a `\"z1\"` side-set is\nassumed, and the receivers will be buried exactly `depth_in_meters` meters\nbelow this side-set.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nchange_id = \"bugfix-absorbing-boundary-width\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix a bug where 1 layer of boundary elements would be added to a Cartesian\nmesh, even if an absorbing boundary width of 0 meters was requested.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nchange_id = \"derive-bm-file-from-cartesian-model\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd a function `derive_bm_file()` to derive a 1-D background model from a 2-\nor 3-D Cartesian volume model. This is useful, for instance, when the 3-D\nmodel has a significant increase in velocity with depth, and when no\nappropriate 1-D model exists a-priori. If the velocity profile allows, using\nthe 1-D model output by this function may result in the insertion of doubling\nlayers when a simulation mesh is created, and as a consequence may allow for\na reduction of computational cost.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix sporadic gradient tests failures in the CI.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nFix MPI deploy and improve validation of the release before uploading to S3.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nchange_id = \"2d-events-in-create-events-from-segy-file\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = true\ndescription = \"\"\"\nMinor modifications to `create_events_from_segy_file` to handle 2-D events.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nchange_id = \"minimal-taper\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nA minimal taper (the first and last 5 samples) will now be applied to every\nwaveform trace before the misfits and adjoint sources are computed in the\n`EventMisfit` object. This should not have any (or only a very minimal) effect\non existing inversions but is more stable in certain edge cases.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nchange_id = \"time-derivative-adjoint-sources\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `EventMisfit` object can now compute fully consistent adjoint sources for\nmeasurements on receivers recording `velocity` or `phi_t` with any misfit\nfunctional. This functionality is also available from within Salvus*Project*.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nchange_id = \"improved-phase-misfit\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe phase misfit now does a better selection of which frequencies to use. One\ncan control which frequency to use and the minimum energy level of the\nfrequencies to use for the phase difference measurement.\n\n```python\nfrom salvus.opt.misfits import get_misfit_function\n\nmisfit, adjoint_source = get_misfit_function(\"phase_misfit\")(\n    data_observed=data_observed,\n    data_synthetic=data_synthetic,\n    sampling_rate_in_hertz=sampling_rate_in_hertz,\n    frequency_limits=(0.1, 0.5),\n    # These two are optional.\n    absolute_value_threshold=1e-3,\n    taper_type=\"hanning\",\n)\n```\n\nThe old implementation is still valid (but not recommended) and can be\naccessed with\n\n```python\nget_misfit_function(\"phase_misfit\", version=1)\n```\n\nExisting projects that used the old phase misfit will keep using it until a\nnew `MisfitConfiguration` has been created.\\\n\"\"\"\n\n[[\"0.11.17\".changes]]\nchange_id = \"improved-time-frequency-phase-misfit\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFixed a bug in the adjoint source scaling of time-frequency adjoint sources\nthat occurred for phase-shifted signals.\n\nAdditionally the time frequency phase misfit is now a lot more flexible with\nmore options.\n\n```python\nfrom salvus.opt.misfits import get_misfit_function\n\nmisfit, adjoint_source = get_misfit_function(\"time_frequency_phase_misfit\")(\n    data_observed=data_observed,\n    data_synthetic=data_synthetic,\n    sampling_rate_in_hertz=sampling_rate_in_hertz,\n    # These two are mandatory.\n    segment_length_in_seconds=15.0,\n    frequency_limits=(0.1, 0.5),\n    # The others are optional.\n    segment_overlap_fraction=0.75,\n    absolute_value_threshold=1e-3,\n    taper_type=\"hanning\",\n    stft_window=\"hann\",\n)\n```\\\n\"\"\"\n\n\n[\"0.11.16\"]\n\nrelease_date = \"2020-09-08\"\nrelease_message = \"\"\"\nThis release comes with several improvements regarding data selection and\ninverse modeling.\n\nThere are no breaking changes in the stable API.\nHowever, the window selection in Salvus*Project* has been completely rewritten,\nand is not compatible with previous versions.\n\nThe new `DataSelectionConfiguration` allows window- and station-dependent\nweights. Furthermore, there are several new options for visualization and\nquality control of misfits. See the `Seismological Gradient` tutorial in the\n`Experimental` section for several examples.\n\nThe mapping function has been extended to offer built-in support for a region\nof interest, and event-dependent masking of sources and receivers to mitigate\nsingularities in the sensitivity kernels.\n\nA new function for uniform mesh refinement and model interpolation has been\nadded to `SalvusMesh`.\n\nThere are several more small changes documented below.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"reference-frame-in-gradient-output\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nInclude the reference frame in the HDF5 gradient output files.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nImprove backward compatibility of the InverseProblemConfiguration\nand fix a bug in the serialization of the mapping function.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"region-of-interest-in-mapping-fct\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded features for defining a region of interest and for\ncutting around sources and receivers in the adjoint mapping\nfunction.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nCompliance with black 0.20 linting.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"box-domain-viz\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nImplement `p.viz.nb.domain()` method for 2D box domains.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"custom-site-configuration-for-inverse-problem\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nMove job submission settings to the InverseProblemConfiguration and\nenable different site configurations for simulations and the preconditioner.\nThe previous way of providing `site_name`, `ranks_per_job` and\n`wall_time_per_job_in_seconds` through the `iterate` and `resume` functions\nstill work, but will be deprecated in the future.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"interactive-misfit-plots\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdd interactive misfit plots to the inverse problem Jupyter notebook widget.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nMajor overhaul of CI.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nAdds the ability to use `mesh_from_domain` with SmoothieSEM via a new\n`MeshParameters` mixin. This allows 3-D models to be interpolated, and also\nallows to lateral refinements to be passed to resolve certain areas better.\nShould not be public yet as it still requires a lot of thought, but there are\na fair amount of tests making sure everything works.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nPlanned to properly scale sources which are located on element boundaries,\nbut ran into some issues in the final validation. On the side, clang-tidied\nup the whole codebase (with restrictions of course, many checks are skipped).\nMerging because of the latter. Until we get a tidy check in the CI, I will\nmaintain compliance.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"robust-adjoint-workflow-with-checkpoints\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nBetter workflow management for misfit and gradient computations.\nThe newly added functionality ensures consistent settings for site name\nand the number of ranks and automatically resubmits simulations if the\ncheckpoints are no longer available.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"progress-bar-spherical-model-interpolation\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nWith very large models and / or meshes, interpolating volumetric models can\ntake some time. Here a 'verbose' argument is now accepted by\n`toolbox.interpolate_spherical`, which will print a progress bar if the\nverbosity is 1 or greater. The verbose behavior is the default when\ngenerating spherical meshes with project.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"handling-of-unstructured-mesh-simulation-configuration\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nBetter error handling and management of entities using\n`UnstructuredMeshSimulationConfiguration` objects.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"smoothiesem-topo-ellipticity-and-ocean-loading\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded ability to create SmoothieSEM meshes with surface as well as Moho\ntopography, ellipticity and ocean loading. Includes several minor bugfixes\nto the SmoothieSEM meshes introduced in the previous release.\n\n```python\nsm = sn.simple_mesh.SmoothieSEM()\n\nsm.basic.model = \"prem_iso_one_crust\"\nsm.basic.min_period_in_seconds = 200.0\nsm.basic.elements_per_wavelength = 2.0\nsm.basic.number_of_lateral_elements = 2\n\nsm.advanced.tensor_order = 4\n\nsm.source.latitude = 38.82\nsm.source.longitude = 40.14\n\n# Ellipticity.\nsm.spherical.ellipticity = 0.0033528106647474805\n\n# Surface topography.\nsm.topography.topography_file = \"topography_earth2014_egm2008_lmax_256.nc\"\nsm.topography.topography_varname = (\n    \"topography_earth2014_egm2008_lmax_256_lmax_16\"\n)\n\n# Moho topography.\nsm.topography.moho_topography_file = \"moho_topography_crust_1_0_egm2008.nc\"\nsm.topography.moho_topography_varname = (\n    \"moho_topography_crust_1_0_egm2008_lmax_16\"\n)\n\n# Ocean loading.\nsm.ocean.bathymetry_file = \"bathymetry_earth2014_lmax_256.nc\"\nsm.ocean.bathymetry_varname = \"bathymetry_earth2014_lmax_256_lmax_16\"\n```\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"dont-throw-adding-inverse-again\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdding an already existing inverse problem configuration again with exactly\nthe same parameters will no longer throw.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"event-window-and-weight-set\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded a new low level `EventWindowAndWeightSet` class. It is a per-event data\nstructure that can be serialized to disc that is able to store interval\nwindows (e.g. windows that have a start as well as an end time). Additionally\nit can store weights at the receiver, component, as well as the individual\nwindow level.\n\nIn most cases this will be utilized through Salvus*Project* but it can be\nused outside of it and it directly integrates with Salvus*Flow*'s `Event` and\n`EventMisfit` infrastructure.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"uniform-mesh-refinement\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded a function to uniformly refine any mesh to double its element count\nalong each dimension and thus doubles its resolved frequency. This should\nwork for arbitrarily complicated meshes including discontinuities. Material\nparameters will be interpolated onto the new elements.\n\n```python\nfrom salvus.mesh.tools.transforms import uniformly_refine\n\nnew_mesh = uniformly_refine(mesh, tensor_order=2)\n```\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"data-selection-configuration\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = true\ndescription = \"\"\"\n**Projects created with an older Salvus version using the `windows` component\ncannot be imported anymore.**\n\nThe `windows` component has been removed in favor of a more generic\n`DataSelectionConfiguration`. This is for one more in line with the rest of\nSalvus*Project* but also more powerful and flexible.\n\nA direct consequence is that any function or object that took a\n`window_set_name` argument now takes a `data_selection_configuration`\nargument.\n\nA `DataSelectionConfiguration` is either a function that is applied on the\nfly to select pieces of data (think generalized windows and weights) or one\n`EventWindowAndWeightSet` set per event (or a combination of both).\n\nProjects that used an on-the-fly temporal weighting/windowing function now have\nto use it by creating a new `DataSelectionConfiguration` with an attached\n`data_selection_function`. The function itself does not have to be changed.\n\n```python\np.add_to_project(\n    sn.DataSelectionConfiguration(\n        name=\"mute_with_direct_phase\",\n        receiver_field=\"phi\",\n        data_selection_function=mute_with_direct_phase,\n    )\n)\n```\n\nThe `pick_windows()` seismological action also requires changing\n`window_set_name` to `data_selection_configuration` (if that configuration\ndoes not yet exist, it will be created). In addition the\n`window_taper_width_in_seconds` argument is now exposed and required. It\ncontrols the width of the taper for the windows.\n\n```python\np.actions.seismology.pick_windows(\n    data_selection_configuration=\"custom_windows\",\n    ...\n    window_taper_width_in_seconds=10.0,\n)\n```\n\nSalvus contains a lot of convenience functions to pick windows and weight\nindividual receivers but it is also possible to directly operate on these\ndata structures for full control.\n\n```python\n# Get the data selection configuration.\ndsc = p.entities.get(\n    entity_type=\"data_selection_configuration\", entity_name=\"custom_windows\"\n)\n# If interval windows have been picked before an event, its\n# `EventWindowAndWeightSet` can be retrieved.\newws = dsc.get_event_window_and_weight_set(event=p.events.get(\"event_0000\"))\n```\n\nThis can than be used to exert detailed control on everything. Once this has\nbeen done it will be applied in all subsequent steps that utilize that\nparticular `DataSelectionConfiguration`.\n\n```python\nIn  [1]: ewws.receivers\nOut [1]:\n{'XX.A0000.': {'receiver_weight': 1.5462720296177797,\n  'components': {'Z': {'component_weight': 1.0,\n    'windows': [{'window_start': 229.67554,\n      'window_end': 1389.219377,\n      'window_weight': 1.0}]},\n...\n\nIn [2]: ewws.receivers[\"XX.A0000.\"][\"receiver_weight\"] = 0.7\n\nIn [3]: ewws.write(overwrite=True)\n```\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"receiver-and-component-weights\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nCan now add weights to individual receivers and components which will then be\napplied to each misfit and adjoint source computation. This could have been\npreviously done with a custom windowing function with weights but this is\nmore convenient and easier to control. It is detailed in other changelog\nitems of this release.\n\nIt can either happen via window picking and receiver weighting or directly in\nthe data selection function:\n\n```python\ndef data_selection_function(st, receiver, sources):\n\n    # Receiver and component weights.\n    weights = {\n        # This is optional but allows to specify additional weights\n        # important for the misfit and adjoint source computations.\n        \"receiver_and_component_weights\": {\n            # Pass the receiver weight here.\n            \"receiver_weight\": 0.75,\n            # It is also possible to give weights to individual\n            # receivers.\n            \"component_weights\": {\"X\": 1.0, \"Y\": 0.8, \"Z\": 0.5},\n        }\n    }\n\n    for tr in st:\n        component = tr.stats.channel[-1]\n        temporal_weights = compute_window(...)\n\n        # Individual window weights.\n        weights[component] = [\n            {\"values\": temporal_weights, \"misfit_weight\": 0.8},\n            ...\n        ]\n\n    return weights\n\n# Add to the project.\np.add_to_project(\n    sn.DataSelectionConfiguration(\n        name=\"custom_data_selection\",\n        receiver_field=\"phi\",\n        data_selection_function=data_selection_function,\n    ),\n    overwrite=True,\n)\n```\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"seismological-receiver-weighting\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded implementations for a few common seismological receiver weighting\nschemes with a general and easy to extend interface.\n\n```python\n# Custom receiver weighting function.\ndef my_favorite_station(event, receivers, receiver_name):\n    weights = {}\n    for name in receivers:\n        if name == receiver_name:\n            weight = 2.0\n        else:\n            weight = 1.0\n        weights[name] = weight\n    return weights\n\n\np.actions.seismology.add_receiver_weights_to_windows(\n    # Add the weights to existing windows in this data selection\n    # configuration.\n    data_selection_configuration=\"custom_windows\",\n    events=p.events.list(),\n    # The weights for each item in the chain will be multiplied together.\n    weighting_chain=[\n        {\n            \"weighting_scheme\": \"ruan_et_al_2019\",\n            \"function_kwargs\": {\"ref_distance_condition_fraction\": 1.0 / 3.0},\n        },\n        {\n            \"weighting_scheme\": \"mute_near_source_receivers\",\n            \"function_kwargs\": {\n                # All receivers closer than this to the sources\n                # will have zero weight.\n                \"minimum_receiver_distance_in_m\": 200e3,\n                # All receivers further away than this will not be muted.\n                \"maximum_receiver_mute_distance_in_m\": 1000e3,\n                # How to go from weight 0 to weight 1 for receivers in the\n                # transition region. Currently only \"hanning\" is supported.\n                \"taper_type\": \"hanning\",\n            },\n        },\n        # Custom weighting function.\n        {\n            \"weighting_scheme\": my_favorite_station,\n            \"function_kwargs\": {\"receiver_name\": \"XX.A0044.\"},\n        },\n    ],\n    # Normalize the sum of all receiver weights to the receiver count.\n    normalize=True,\n)\n```\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"receiver-weight-map\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nNew seismological receiver weight map plot.\n\n```python\np.viz.seismology.receiver_weights_map(\n    data_selection_configuration=\"custom_windows\"\n)\n```\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"function-serialization\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nVarious part of Salvus*Project* can serialize functions to disc. This is now\nmore powerful and easier to use as the serialized functions can now access\nclosure values as well as other variables in the global scope of the\nfunctions which will also be serialized alongside. Thus external variables\nand imports will now work with these functions.\n\nBasically it means that it should now just work in more cases without any\nextra work or rewrites.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"misfit-per-receiver-map-widget\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `p.viz.seismology.misfit_map()` method is now a widget and the event can\nbe selected interactively. Thus passing the `event` argument is no longer\nnecessary.\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"misfit-histograms\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nNew method to visualize and compare histograms of misfits.\n\n```python\np.viz.misfit_histogram(\n    simulation_configuration_a=\"initial_model_70_120_seconds\",\n    simulation_configuration_b=p.inversions.get_simulation_name(\n            inverse_problem_configuration=\"inversion\", iteration_id=25\n    ),\n    misfit_configuration=\"phase_misfit_70_120_seconds\",\n    events=p.events.list(),\n    merge_all_components=False\n)\n```\\\n\"\"\"\n\n[[\"0.11.16\".changes]]\nchange_id = \"interval-window-tables\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nA few new utilities to analyze the statistics of interval windows.\n\nOne is the ability to get a `pandas.DataFrame` object containing statistics\nabout all windows for a list of events. This is very useful to do some custom\nanalysis and figure out which events to use in the final inversion.\n\n```python\ndf = p.entities.get(\n    entity_type=\"data_selection_configuration\", entity_name=\"selection_a\"\n).get_interval_window_statistics_table(events=p.events.get_all())\n```\n\nA styled version of this table with all events in a project can be visualized\nwith:\n\n```python\np.viz.interval_window_statistics(\"selection_a\")\n```\\\n\"\"\"\n\n[\"0.11.15\"]\n\nrelease_date = \"2020-08-13\"\nrelease_message = \"\"\"\nThis release features a revamp of the mesh masking interface to be more\nflexible as well as easier to use. Additionally it contains a first version\nof global and continental scale wavefield adapted SmoothieSEM meshes.\n\nFurthermore it includes a new receiver collection and the ability to retrieve\ndetailed misfit information from an `EventMisfit` object. Last but not least\nit includes a bugfix for gradients in meshes employing the region-of-interest\nfeature while using nontrivial checkpoints.\n\nFor the experimental Salvus*Project* packages it contains a number of\nquality-of-life to visualize and understand misfits in more detail as well as\na number of bugfixes and some polish.\n\nThis update has no user facing breaking changes (aside the mesh masking) so\nwe recommend this update to all users.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nproduct = \"SalvusMesh\"\npublic_change = false\ndescription = \"\"\"\nImproved/Added docstrings to the `UnstructuredMesh` class as well as cleaning\nup its API.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nTag releases from the CI.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"disable-non-displacement-and-phi-adjoint-sources\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nWarn when receiver fields other than `\"displacement\"` or `\"phi\"` are used in\na `MisfitConfiguration` object. Otherwise the adjoint sources are currently\nnot fully consistent.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"fix-checkpoints\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nBugfix for the region of interest in adjoint runs with nontrivial checkpoints.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nDon't upload test artifacts.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\n`SalvusCompute`: Add compiler warnings and prepare for clang-tidy.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"get-side-set-nodes\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew method `UnstructuredMesh.get_side_set_nodes()` to get all nodes in a side\nset.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"new-mask-generators\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = true\ndescription = \"\"\"\nNew mask generators (`SurfaceMaskGenerator`, `RayMaskGenerator`) replacing\nthe existing JSON based masking interface.\n\nThey are now applied via the `processing_function` argument to the\ncentral `run_mesher()` function.\n\nWe expect this to only affect a small number of users.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"smoothiesem\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAdded the ability to generate wavefield adaptive spectral-element meshes\nwhich we refer to as `SmoothieSEM`.\n\n```python\nsm = sn.simple_mesh.SmoothieSEM()\n\nsm.basic.model = \"prem_iso_one_crust\"\nsm.basic.min_period_in_seconds = 200.0\nsm.basic.elements_per_wavelength = 2.0\nsm.basic.number_of_lateral_elements = 4\n\nsm.advanced.tensor_order = 2\nsm.source.latitude = 35.0\nsm.source.longitude = 12.0\n```\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAdd python integration tests and `ccache`.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nNo longer filter numpy's `tostring()` deprecation warning in the pytest\nconfiguration.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"misfit-per-receiver\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew `EventMisfit.misfit_per_receiver_and_component_and_weight_set` attribute\nto yield a more detailed view of how the misfit for a single event is\ncomputed.\n\n\n```python\nIn [1]: ed.misfit_per_receiver_and_component_and_weight_set\n\nOut [1]:\n{'XX.A0000.': {'Z': [0.00088682823102153761],\n  'N': [0.000256782248385296],\n  'E': [0.00012302960702887129, 0.0004303495400]},\n 'XX.A0001.': {'Z': [0.0010641578304181843],\n  'N': [0.00025058292454050639],\n  'E': [0.00012369945631215902]},\n  ...\n}\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"misfit-per-receiver-table\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nNew `p.misfits.get_misfit_comparison_table()` method yielding a\n`pandas.DataFrame` containing detailed per-receiver misfit information that\ncan be used for further custom analysis.\n\n```python\nIn [1]: p.misfits.get_misfit_comparison_table(\n            reference_data=\"initial_model\",\n            other_data=[\n                p.inversions.get_simulation_name(\n                    inverse_problem_configuration=\"inv\", iteration_id=4\n                )\n            ],\n            misfit_configuration=\"L2-misfit-to-target-model\",\n            event=\"event_0000\",\n        )\n\nOut [1]:\n           initial_model (ref)  inv_it_3__trial   Reduction inv_it_3__trial\nXX.A0000.      1.266640e-03     0.000224           0.001043\nXX.A0001.      1.438440e-03     0.000361           0.001078\nXX.A0002.      1.450685e-03     0.000369           0.001081\nXX.A0003.      1.607995e-03     0.000430           0.001178\nXX.A0004.      9.473526e-04     0.000238           0.000709\n...                     ...          ...                ...\nXX.A0095.      1.182061e-05     0.000065          -0.000053\nXX.A0096.      1.360653e-06     0.000529          -0.000527\nXX.A0097.      9.762485e-07     0.000102          -0.000101\nXX.A0098.      4.663780e-06     0.000306          -0.000301\nXX.A0099.      1.784453e-06     0.000165          -0.000163\n\n[100 rows x 3 columns]\n```\\\n\"\"\"\n\n\n[[\"0.11.15\".changes]]\nchange_id = \"misfit-per-receiver-table-view\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nNew `p.viz.nb.misfit_comparison()` method to display the output from the\n`p.misfits.get_misfit_comparison_table()` method in a pretty table.\n\n```python\np.viz.nb.misfit_comparison(\n    reference_data=\"initial_model\",\n    other_data=[\n        p.inversions.get_simulation_name(\n            inverse_problem_configuration=\"inv\", iteration_id=4\n        )\n    ],\n    misfit_configuration=\"L2-misfit-to-target-model\",\n    event=p.events.list()[0],\n)\n```\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"misfit-per-receiver-map\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nNew `p.viz.seismology.misfit_map()` method to display the output from the\n`p.misfits.get_misfit_comparison_table()` method on a geographical map.\n\n```python\np.viz.seismology.misfit_map(\n    reference_data=\"initial_model\",\n    compare_data=p.inversions.get_simulation_name(\n            inverse_problem_configuration=\"inv\", iteration_id=5\n        ),\n    misfit_configuration=\"L2-misfit-to-target-model\",\n    event=p.events.list()[0],\n)\n```\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"delete-entities\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nCan now delete entities, even if they cannot be instantiated anymore. Useful\nfor certain edge cases.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nDocumentation generation for the SalvusMesh schema.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"side-set-grid-point-3d\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nNew `simple_config.receiver.seismology.collections.SideSetGridPoint3D`\nreceiver collection.\n\n```python\nlat_c, lon_c = 45.0, 10.0\nlat_e, lon_e = 15.0, 18.0\n\nreceivers = sn.simple_config.receiver.seismology.collections.SideSetGridPoint3D(\n    lat_center=lat_c,\n    lat_extent=lat_e * 0.9,\n    lon_center=lon_c,\n    lon_extent=lon_e * 0.9,\n    fields=[\"displacement\"],\n    n_lat=10,\n    n_lon=10,\n)\n```\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"is-in-domain-spherical-chunks\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nFully consistent `is_point_in_domain()` check for spherical chunk domains.\\\n\"\"\"\n\n[[\"0.11.15\".changes]]\nchange_id = \"spherical-chunks-map-viz\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nThe map visualization for spherical chunks now also works for domains\ncrossing the international date line.\n\n```python\nsn.domain.dim3.SphericalChunkDomain(\n    lat_center=52.0,\n    lat_extent=16.0,\n    lon_center=170.0,\n    lon_extent=66.0,\n    radius_in_meter=6371000.0,\n).plot()\n```\\\n\"\"\"\n\n[\"0.11.14\"]\n\nrelease_date = \"2020-07-29\"\nrelease_message = \"\"\"\nThis release contains a few minor user facing improvements for the stable\npart of Salvus but it largely focusses on improvements for the experimental\nSalvus*Project* module.\n\nThe release is fully backwards compatible so we recommend all users to\nupdate.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nchange_id = \"quality-of-life-improvements\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nA few quality-of-life improvements for inversions.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nchange_id = \"mapping-interface\"\nproduct = \"SalvusOpt\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nGeneric mapping interface to transform inversion models between physical and\nsimulation space.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nRemove some unreachable Python code.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nRaise for visco-acoustic simulations in SalvusFlow and SalvusCompute.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nchange_id = \"uppercase-model-vars\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nUppercase variables names during model interpolation from xarray data sets\nand NetCDF files. Thus lowercase case variables now also work.\\\n\"\"\"\n\n\n[[\"0.11.14\".changes]]\nchange_id = \"inversion-widgets-improvements\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nSeveral improvements and small bug fixes in a number of Jupyter notebook\ninversion widgets.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nchange_id = \"smoothing-inversion-action\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nNew inversion action to faciliate model smoothing.\n\n```python\np.actions.inversion.smooth_model(\n    model=gradient,\n    smoothing_configuration=sn.ConstantSmoothing(\n        smoothing_lengths_in_meters={\"VP\": 0.01, \"RHO\": 0.01,},\n    ),\n    ranks_per_job=4,\n    site_name=\"local\",\n)\n```\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nproduct = \"SalvusCompute\"\npublic_change = false\ndescription = \"\"\"\nInitial implementation of subsampled gradients.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nproduct = \"SalvusProject\"\npublic_change = false\ndescription = \"\"\"\nAdd comprehensive gradient tests.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nInitial implementation of py.test integration tests.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nchange_id = \"zero-width-abc\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nFix the ABC element field for zero-width absorbing boundaries for proper\nvisuzliations. This only affected visualizations and had no effect on the\nsimulations.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nchange_id = \"dataless-misfits\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nEnable misfit configurations without observed data.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nchange_id = \"check-deserializability-for-functions\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nPrevent processing/misfit functions that cannot be deserialized again from\nbeing stored in a project in the first place.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nOptionally use `ccache` during the cmake build process.\\\n\"\"\"\n\n\n[[\"0.11.14\".changes]]\nchange_id = \"reference-time-in-all-outputs\"\nproduct = \"SalvusCompute\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nAll wavefield outputs now have a `reference_time_in_seconds` attribute. Thus\nalso receiver output in the HDF5 block format can now be absolutely located\nin time and not just ASDF files.\\\n\"\"\"\n\n\n[[\"0.11.14\".changes]]\nchange_id = \"mesh-widget-color-map-slider\"\nproduct = \"SalvusMesh\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nSlider to change the min/max values of the colormap in the Jupyter notebook\nmesh visualization widget.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nAbility to run the integration tests only for a certain PETSc precision.\\\n\"\"\"\n\n\n[[\"0.11.14\".changes]]\nproduct = \"Meta\"\npublic_change = false\ndescription = \"\"\"\nIntegration tests to make sure the references time + associated adjoint\nsources work within and outside of SalvusProject. Now also works correctly\noutside of SalvusProject.\\\n\"\"\"\n\n\n[[\"0.11.14\".changes]]\nchange_id = \"2d-circular-domain\"\nproduct = \"SalvusProject\"\npublic_change = true\npart_of_stable_api = false\nbreaks_existing_api = false\ndescription = \"\"\"\nNew experimental 2-D circular domain.\\\n\"\"\"\n\n\n[[\"0.11.14\".changes]]\nchange_id = \"temporal-weight-function-checks\"\nproduct = \"SalvusFlow\"\npublic_change = true\npart_of_stable_api = true\nbreaks_existing_api = false\ndescription = \"\"\"\nThe `EventData` object will now raise an exception if a temporal weight\nfunction returns components that the data cannot have.\\\n\"\"\"\n\n[[\"0.11.14\".changes]]\nproduct = \"SalvusFlow\"\npublic_change = false\ndescription = \"\"\"\nNot necessarily useful but allow adjoint sources to be written by the\n`EventMisfit` object.\\\n\"\"\"\n\n\n[older_changelogs]\n\npublic_older_changelog_contents = \"\"\"\n### 0.11.13\n\nReleased: _July 16<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusMesh`: Fix side-sets for masked global domains.\n- `SalvusCompute`: Minor bug fix for safely writing the meta json.\n- `SalvusCompute`: Auto-time-step detection for the diffusion equation.\n- `SalvusFlow`: Removed the `cpu_count` argument from all functions\n  performing receiver/source placement. It was not actually any faster and we\n  have to re-evaluate the chosen approach.\n- `SalvusFlow`: More control over the end time when using a\n  `FilteredHeaviside` source time function.\n- `SalvusFlow`: The `FilteredHeaviside` STFs now defaults to 3 lowpass filter\n  corners and additionally allows explicitly settings the sampling rate.\n  **changed defaults**\n\n**Experimental features:**\n\n- `SalvusOpt`: New implementation of time-frequency phase misfits.\n- `SalvusOpt`: Added new phase misfit.\n- `SalvusOpt`: Bug fix for scaling of cross-correlation adjoint sources.\n- `SalvusProject`: Correctly plot the time axis for seismological data.\n- `SalvusProject`: More stable and informative window picking process.\n- `SalvusProject`: Statistical window visualizations.\n- `SalvusProject`: The window picking action can now work with external\n  window picking functions. **API change**\n- `SalvusProject`: Function serialization now works with imports as well as\n  closure variables making it a lot more flexible.\n- `SalvusProject`: The window picking action can now optionally also only act\n  on a subset of receivers and not store the results in the project. Useful\n  for debugging and tuning of the window picking process.\n- `SalvusProject`: All specialized processing configurations have been moved\n  to functions. The only remaining processing configurations are\n  `ProcessingConfiguration` and `SeismologyProcessingConfiguration`. The old\n  ones are deprecated but will stay around for the rest of the lifecylce of\n  Salvus 0.11.x. Please move to the new way of doings things. **API change**\n- `SalvusProject`: The `compute_window()` function has been moved to\n  `salvus.project.tools.windows`. **API change**\n- `SalvusProject`: Adding optional `time_step_in_seconds` to the\n  `WaveformSimulationConfiguration` constructor.\n\n### 0.11.12\n\nReleased: _July 2<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusMesh`: Still attach absorbing side sets if the number of wavelengths\n  is zero for Cartesian meshes.\n- `SalvusFlow`: Various optimizations to improve the speed of job arrays.\n- `SalvusFlow`: Various optimizations for simple config objects.\n- `SalvusProblem`: Tags in ASDF output will now always correspond to the\n  receiver field names. It is thus consistent with the input as well as the\n  HDF5 output. **API change**\n- `SalvusCompute`: Compatibility with the ppc64le CPU architecture.\n\n**Experimental features:**\n\n- `SalvusProject`: Make event names in EventCollections customizable.\n- `SalvusOpt`: Improve trust-region scaling.\n- `SalvusProject`: Consistent coordinate order for all models (volume,\n  topography, bathymetry).\n\n### 0.11.11\n\nReleased: _June 22<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusCompute`: Add a check for NaNs in the time loop of CUDA runs.\n- `SalvusMesh`: More control over mesh file size, improved documentation.\n- `SalvusCompute`: Speedup gradient postprocessing, especially for\n  anisotropic models.\n- `SalvusCompute`: Compliance with CWE/SANS Top 25.\n\n**Experimental features:**\n\n- `SalvusOpt`: Auto-detect gradient parameterization from the model.\n  **API change**\n- `SalvusProject`: Fix tmp file handling on foreign file systems.\n- `SalvusProject`: Fix bug in bathymetry dataset loading and improved test\n  coverage.\n- `SalvusProject`: Iteration widget for notebook visualization.\n- `SalvusOpt`: Simplified interfaces for diffusion-based preconditioning.\n\n### 0.11.10\n\nReleased: _June 12<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusCompute`: Fix allocation bug for adjoint absorbing boundaries on GPUs.\n- `SalvusFlow`: If files (e.g. meshes, source time functions, ...) are shared\n  between multiple jobs in a job array they will only be uploaded once to the\n  remote site and shared between jobs.\n- `SalvusFlow`: Optimized usage of SalvusFlow's internal job database.\n- `SalvusFlow`: Can now deal with `ProxyJump` settings in SSH config files.\n\n**Experimental features:**\n\n- `SalvusProject`: Fix domain vis. for sph. chunk domains, and improve it for\n  UTM domains.\n- `SalvusProject`: Add events from custom ASDF files.\n- `SalvusProject`: Inversion action component for misfit and gradient\n  computations.\n- `SalvusOpt`: Support for fully asynchronous inversions.\n\n### 0.11.9\n\nReleased: _June 5<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusMesh`: Fix ocean load for orders > 1\n- `SalvusFlow`: Improved validation of diffusion input\n- `Docs`: Render doc strings for methods inherited from abstract methods.\n\n**Experimental features:**\n\n- `SalvusProject`: Fix side set handling for masked spherical chunks\n- `SalvusOpt`: More robust trace interpolation for misfit computations\n\n### 0.11.8\n\nReleased: _May 26<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusFlow`: Increase default verbosity of `simulations.launch()`\n  to `2`\n- `SalvusCompute`: Small bug fixes in receiver handling.\n- `SalvusCompute`: Compile for additional CUDA device architectures.\n- `Meta`: Refined parameter validation in JSON schema\n\n**Experimental features:**\n\n- `SalvusProject`: Propagate NANs as a mask from spherical to cartesian\n  models.\n- `SalvusProject`: Make Courant number configurable in WaveformSimulationConfiguration\n\n### 0.11.7\n\nReleased: _May 19<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusCompute`: Remove spurious device sync.\n- `SalvusCompute`: Adjoing simulations and gradients on GPUs.\n\n### 0.11.6\n\nReleased: _May 8<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusCompute`: Implement a `MeshPartitioner` class to encapsulate\n  partitioning (including deterministic re-partitioning).\n\n### 0.11.5\n\nReleased: _April 29<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusCompute`: Temporarily disable multiple checkpoints.\n- `SalvusCompute`: Fix some edge cases in handling checkpoints\n- `SalvusCompute`: Ensure unique boundary conditions on side sets.\n- `SalvusFlow`: Fix upgrading remote sites for incompatible versions.\n- `SalvusFlow`: Validate side-sets for output and boundary conditions.\n- `SalvusFlow`: Enable manual SSH password entry.\n- `SalvusFlow`: Optionally use a login shell to execute commands at a site.\n- `SalvusFlow`: More flexible in regards to any extra output added by a job\n  management system.\n- `SalvusFlow`: New features for LSF sites:\n  - Enable `{RANKS}`, `{NODES}`, and `{TASKS_PER_NODE}` variables in `mpirun`\n    replacement as well as all bsub arguments.\n  - Optional tasks per node setting.\n  - Ability to set environment variables in batch script instead of the command\n- `SalvusMesh`: Ensure that additional ABC elements are strictly outside of the\n  domain.\n- `SalvusToolbox`: `dimensionless` is now an acceptable unit for parameters\n  that do not have units in the IRIS EMC model reader.\n- `SalvusToolbox`: Read attenuation models with the IRIS EMC model reader.\n\n**Experimental features:**\n\n- `SalvusProject`: Better support for oceans and ocean loading.\n- `SalvusProject`: Notebook visualization of spherical domains.\n\n### 0.11.4\n\nReleased: _April 17<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusCompute`: Better estimate of the sampling interval required to\n  buffer fields during a checkpoint run. Relevant for simulations with\n  attenuation.\n- `SalvusFlow`: Increase wall-time of `init-site` job.\n- `SalvusFlow`: Correctly distinguish and upload files if they have the same\n  name but different local folders.\n\n### 0.11.3\n\nReleased: _April 16<sup>th</sup> 2020_\n\nUnfortunately the standard upgrading route of running:\n\n`salvus-flow upgrade`\n\nwill not work for this particular release. We apologize for any caused\ninconvenience. Please re-run the Mondaic downloader instead:\n\n`bash -c \"$(curl -sSL https://get.mondaic.com)\"`\n\nand select version `0.11.3` or higher. Make sure to follow all the\ninstallation steps, especially the one regarding `pip install salvus*.whl`.\nOnce the installation process is complete, the acquisition issue should be\nfixed. `salvus-flow upgrade` should work for any future changes.\n\n**Changes:**\n\n- `Meta`: Adapted license check to server side changes.\n- `Meta`: New `salvus` CLI command that is a strict alias to the existing\n  `salvus-flow` CLI command. We plan on keeping both for the foreseeable\n  future.\n- `Meta`: New `salvus --version`/`salvus-flow --version` CLI command to\n  retrieve the current Salvus version number at a glance.\n\n### 0.11.2\n\nReleased: _April 10<sup>th</sup> 2020_\n\n**Changes:**\n\n- `SalvusFlow`: Enforce that the local Python Salvus version is identical to\n  the remote Salvus*Compute* version.\n- `SalvusFlow`: Automatically reinitialize all matching local sites upon\n  `salvus-flow upgrade`.\n- `SalvusFlow`: Recommend a list of suitable remote sites to update after\n  `salvus-flow upgrade` has finished.\n- `SalvusFlow`: Make sure the run and temp directories are not in the folder\n  managed by the Mondaic downloader.\n\n### 0.11.1\n\nReleased: _April 3<sup>rd</sup> 2020_\n\n**Changes:**\n\n- `SalvusCompute`: More robust estimation of wavefield buffer sizes for\n  checkpointing.\\\n\"\"\"\n\nprivate_older_changelog_contents = \"\"\"\n## 0.11.13\n\n- `SalvusMesh`: Fix side-sets for masked global domains.\n- `SalvusCompute`: Minor bug fix for safely writing the meta json.\n- `SalvusOpt`: New implementation of time-frequency phase misfits.\n- `SalvusOpt`: Added new phase misfit.\n- `SalvusOpt`: Bug fixes scaling of CC adjoint sources.\n- `SalvusCompute`: Auto-time-step detection for the diffusion equation.\n- `Meta`: Use Ninja to run builds.\n- `SalvusProject`: Utility to (de)serialize classes.\n- `SalvusProject`: Function serialization now works with imports as well as\n  closure variables making it a lot more flexible.\n- `SalvusFlow`: Removed the `cpu_count` argument from all functions\n  performing receiver/source placement. It was not actually any faster and we\n  have to re-evaluate the chosen approach. **API change**\n- `SalvusFlow`: More control over the end time when using a\n  `FilteredHeaviside` source time function.\n- `SalvusProject`: Correctly plot the time axis for seismological data.\n- `SalvusProject`: More stable and informative window picking process.\n- `SalvusProject`: Statistical window visualizations.\n- `SalvusProject`: The window picking action can now work with external\n  window picking functions. **API change**\n- `SalvusProject`: The window picking action can now optionally also only act\n  on a subset of receivers and not store the results in the project. Useful\n  for debugging and tuning of the window picking process.\n- `SalvusProject`: All specialized processing configurations have been moved\n  to functions. The only remaining processing configurations are\n  `ProcessingConfiguration` and `SeismologyProcessingConfiguration`. The old\n  ones are deprecated but will stay around for the rest of the lifecylce of\n  Salvus 0.11.x. Please move to the new way of doings things. **API change**\n- `SalvusProject`: The `compute_window()` function has been moved to\n  `salvus.project.tools.windows`. **API change**\n- `SalvusProject`: Adding `time_step_in_seconds` to the\n  `WaveformSimulationConfiguration` constructor.\n- `SalvusFlow`: The `FilteredHeaviside` STFs now defaults to 3 lowpass filter\n  corners and additionally allows explicitly settings the sampling rate.\n  **API change**\n\n## 0.11.12\n\n- `SalvusMesh`: Still attach absorbing side sets if the number of wavelengths is\n  zero for Cartesian meshes.\n- `Meta`: Various improvements to accelerate a synthetic Marmousi FWI.\n- `SalvusCompute`: Compile CUDA code with clang-10.0.\n- `SalvusProject`: Make event names in EventCollections customizable.\n- `SalvusOpt`: Improve trust-region scaling\n- `SalvusFlow`: Various optimizations for simple config objects.\n- `SalvusProblem`: Tags in ASDF output will now always correspond to the\n  receiver field names. It is thus consistent with the input as well as the\n  HDF5 output.\n- `SalvusCompute`: Compatibility with the ppc64le CPU architecture.\n- `SalvusProject`: Consistent coordinate order for all models (volume,\n  topography, bathymetry).\n\n## 0.11.11\n\n- `SalvusCompute`: Add a check for NaN in the time loop of CUDA runs.\n- `SalvusOpt`: Auto-detect gradient parameterization from the model.\n  **API change**\n- `SalvusProject`: Fix tmp file handling on foreign file systems.\n- `SalvusProject`: Fix bug in bathymetry dataset loading and improved test\n  coverage.\n- `SalvusProject`: Iteration widget for notebook visualization.\n- `SalvusOpt`: Simplified interfaces for diffusion-based preconditioning.\n- `SalvusMesh`: More control over mesh file size, improved documentation\n- `SalvusCompute`: Speedup gradient postprocessing, especially for\n  anisotropic models.\n- `SalvusCompute`: Compliance with CWE/SANS Top 25 for SAST report\n- `Meta`: SAST analysis in CI\n- `SalvusProject`: Models with symlinks whose source file did not actually\n  exist where added with invalid symlinks which prevented adding them again.\n  Fixed this by making sure the sources files exist at every stage.\n- `SalvusProblem`: Testing communicator and not rank to determine if current\n  processor is part of the communicator.\n\n## 0.11.10\n\n- `SalvusProject`: Fix domain vis. for sph. chunk domains, and improve it for\n  UTM domains.\n- `SalvusCompute`: Fix allocation bug for adjoint absorbing boundaries on GPU.\n- `SalvusProject`: Add events from custom ASDF files.\n- `SalvusCompute`: Refactor L2gMap class and bring in async phase 1.\n- `SalvusProject`: Inversion action component for misfit and gradient\n  computations.\n- `SalvusOpt`: Support for fully asynchronous inversions.\n- `SalvusFlow`: If files (e.g. meshes, source time functions, ...) are shared\n  between multiple jobs in a job array they will only be uploaded once to the\n  remote site and shared between jobs.\n- `SalvusFlow`: Optimized usage of SalvusFlow's internal job database.\n- `Meta`: Require `ujson >= 3.0.0`.\n- `SalvusFlow`: Can now deal with `ProxyJump` settings in SSH config files.\n\n## 0.11.9\n\n- `SalvusProject`: Fix side set handling for masked spherical chunks\n- `SalvusOpt`: More robust trace interpolation for misfit computations\n- `SalvusMesh`: Fix ocean load for orders > 1\n- `SalvusFlow`: Improved validation of diffusion input\n- `CI`: Update ssh settings for ths instaseis benchmarks\n- `Meta`: Methods inherited from abstract methods should not be properly\n  documented.\n\n## 0.11.8\n\n- `SalvusFlow`: Skip receivers (instead of failing) if duplicate coordinate\n  are detected.\n- `SalvusFlow`: Fail at validation stage if point_output is requested but no\n  receivers are specified. Increase default verbosity of `simulations.launch()`\n  to `2`\n- `SalvusCompute`: Throw proper exception if point_output is requested but no\n  receivers are specified.\n- `SalvusCompute`: Compile for additional CUDA device architectures.\n- `Meta`: Getting rid of all \"high\" `bandit` issues and manually\n  auditing and accepting all \"medium\" ones.\n- `SalvusProject`: Propagate NaNs as a mask from spherical to cartesian\n  models.\n- `SalvusProject`: Make Courant number configurable in WaveformSimulationConfiguration\n- `Meta`: Refined parameter validation in JSON schema\n\n## 0.11.7\n\n- `SalvusCompute`: Remove spurious device sync.\n- `SalvusCompute`: Adjoint simulations and gradients on GPUs.\n- `SalvusPy`: Compliance with flake8 3.8.1\n- `LicenseClient`: Properly handle spaces in license group names.\n\n## 0.11.6\n\n- `SalvusMesh`: Use anisotropic refinement for lateral ocean refinements.\n- `SalvusMesh`: Fix side set visualization in 3D in paraview with xdmf files\n- `SalvusMesh`: By default only write model to xdmf, more control on what is\n  written by `mode` keyword of `write_h5` function\n- `SalvusCompute`: Save partition for later re-creation using\n  `PetscPartitionerShell` during adjoint runs.\n- `SalvusCompute`: Working towards adjoints on GPUs, a better async approach\n  for MPI, and a benchmarking tool.\n- `SalvusProject`: Call `pyproj` functions in a more modern way.\n- `SalvusCompute`: Implement a `MeshPartitioner` class to encapsulate\n  partitioning (including deterministic re-partitioning).\n\n## 0.11.5\n\n- `SalvusCompute`: Temporarily disable multiple checkpoints.\n- `SalvusCompute`: Fix some edge cases in handling checkpoints\n- `SalvusFlow`: Fix upgrading remote sites for incompatible versions.\n- `SalvusCompute`: Ensure unique boundary conditions on side sets.\n- `SalvusFlow`: Validate side-sets for output and boundary conditions.\n- `SalvusProject`: Better support for oceans and ocean loading.\n- `SalvusFlow`: Enable manual SSH password entry.\n- `SalvusFlow`: Optionally use a login shell to execute commands at a site.\n- `SalvusFlow`: More flexible in regards to any extra output added by a job\n  management system.\n- `SalvusFlow`: New features for LSF sites:\n  - Enable `{RANKS}`, `{NODES}`, and `{TASKS_PER_NODE}` variables in `mpirun`\n    replacement as well as all bsub arguments.\n  - Optional tasks per node setting.\n  - Ability to set environment variables in batch script instead of the command\n    line.\n- `SalvusMesh`: Ensure that additional ABC elements are strictly outside of the\n  domain.\n- `SalvusProject`: General improvements to data handling.\n- `SalvusProject`: Notebook visualization of spherical domains.\n- `SalvusProject`: New `p.viz.nb.domain()` method.\n- `SalvusToolbox`: `dimensionless` is now an acceptable unit for parameters\n  that do not have units in the IRIS EMC model reader.\n- `SalvusToolbox`: Read attenuation models with the IRIS EMC model reader.\n\n## 0.11.4\n\n- `SalvusProblem`: Better estimate of the sampling interval required to\n  buffer fields during a checkpoint run. Relevant for simulations with\n  attenuation.\n- `Salvus-Flow`: Increase wall-time of `init-site` job.\n- `SalvusFlow`: Correctly distinguish and upload files if they have the same\n  name but different local folders.\n\n## 0.11.3\n\n- `Meta`: Fixing bug in the license client with larger HTTP package sizes.\n- `Meta`: New `salvus` CLI command that is a strict alias to the existing\n  `salvus-flow` CLI command. We plan on keeping both for the foreseeable\n  future.\n- `Meta`: New `salvus --version`/`salvus-flow --version` CLI command to\n  retrieve the current Salvus version number at a glance.\n\n## 0.11.2\n\n- `SalvusFlow`: Enforce that the local Python Salvus version is identical to\n  the remote SalvusCompute version.\n- `SalvusFlow`: Automatically reinitialize all matching local sites upon\n  `salvus-flow upgrade`.\n- `SalvusFlow`: Recommend a list of suitable remote sites to update after\n  `salvus-flow upgrade` has finished.\n- `SalvusFlow`: Make sure the run and temp directories are not in the folder\n  managed by the Mondaic downloader.\n\n## 0.11.1\n\n- `SalvusCompute`: Fix buffering for checkpointing.\n\n## 0.11\n\n- `SalvusProblem`: Remove debugging stdout from CUDA adjoint run.\n- `SalvusProblem`: Fix issue in Cuda custom source test.\n- `SalvusProblem`: Check incorrect datasets in block sources, throw if Cuda is\n  tried for Adjoint, custom STF works on GPU.\n- `SalvusProject`: Add ipyleaflet map and spherical to cartesian model.\n- `SalvusMesh`: Test for placing receivers from parse function with geographic\n  latitude.\n- `Physics`: Added `-ffast-math` to compile flags for gradient computations.\n- `Project`: Oceans in 2- and 3-D UTM\n- `Project`: Allow non side set seismological sources for spherical domains.\n- `Project`: Initial support for bathymetry in cartesian domains (3-D).\n- `Meta`: Add reporter to gitlab-ci.\n- `Meta`: Fingerprint was failing on osx -- at least see why.\n- `Meta`: Refactor cmake.\n- `Meta`: Fixing wheel validation.\n- `SalvusProject`: Default to anisotropic doubling for spherical meshes.\n- `SalvusProblem`: Turn on parallel mesh loading.\n- `SalvusProblem`: Surface output on GPUs\n- `SalvusMesh`: Allow for explicit passing of constant Q band to some simple\n  constructors.\n- `SalvusCompute`: Attenuation on CUDA GPUs.\n- `SalvusMesh`: Increases max depth of sph. abs. lay. to 75% of radius.\n- `SalvusCompute`: Adds CUDA support for absorbing layers.\n- `SalvusProject`: Visualization of simulation configurations without events.\n- `SalvusProject`: Use different lmax for Moho and fix relative interpolation\n- `SalvusCompute`: Output rho-vp gradients in acoustic when requesting TTI in el.\n- `CI`: Add open ssh server to test remote site in CI\n- `CI`: Test site init, downloading, upgrading, ... in the CI\n- `SalvusFlow`: Improve init site\n- `SalvusFlow`: Better error message when the JSON output parsing fails.\n- `SalvusCompute`: Support for `gcc-5.4`\n- `SalvusFlow`: `salvus-flow add-site` now also installs Salvus at the remote\n  sites.\n- `SalvusFlow`: `salvus-flow upgrade` to update the local Salvus Python\n  installation.\n- `SalvusFlow`: `salvus-flow upgrade-site` to update a remote Salvus site.\n- `SalvusFlow`: The module switching/(un)loading in the LSF site can now also\n  happen inside the batch file.\n- Fixing `mypy` and the docstrings.\n- `SalvusOpt`: Initial version of ASDF gradient support\n- Remove deprecated python packages\n- `SalvusProject`: Attempting to get version-independent hashes.\n- `SalvusProject`: Add a hash store to be able to do the inverse mapping from\n  hash to object.\n- Ensure identical version numbers for cpp and py for untagged releases.\n- `SalvusOpt`: Fix and improve adjoint source tests, various fixed for\n  inversion tutorial.\n- `CI`: Fix and add missing tests\n- `SalvusProject`: Small fixes to ensure compatibility with the tutorials.\n- `SalvusOpt`: More general misfit handling for asdf data\n- `SalvusFlow`: Small fix for new mypy\n- `SalvusMesh`: Auto-band is now the default in the mesher.\n- `SalvusProject`: Begin to allow meshing a two 2D BM file domain.\n- `SalvusCompute`: Add ocean loading\n- `SalvusProject`: Workaround to the make the spherical mesher work with BM\n  files.\n- `SalvusProject` + `SalvusToolbox`: Adjust regression data for scipy>1.4.0\n  and force a Scipy >= 1.4.1\n- `SalvusMesh`: Cleaner way in how the big schema is split up into individual\n  sub-schemas.\n- `SalvusFlow`: Site can be updated with schema changes.\n- `SalvusProject`: Use the Courant number from the forward run for the\n  adjoint run.\n- `SalvusMesh`: Removing the deprecated `salvus.mesh.simple_config`.\n- `SalvusProject`: Sources and receivers are asserted to be part of the\n  domain when being added to a project.\n- `SalvusProject`: Unified model handling across volume, topography, and\n  bathymetry models.\n- `SalvusFlow`: The direction vector for side set sources and receiver must\n  now always be a proper vector.\n- `SalvusFlow`: The environment variables on slurm are now explicitly passed\n  in the sbatch file. Thus the environment variables set in the startup\n  dotfiles no longer pollute the Salvus run.\n- `SalvusFlow`: `run()` and `run_many()` now print the correct initial status\n  instead of always defaulting to `\"running\"`.\n- `SalvusFlow`: Ability to force update job and job arrays.\n- `SalvusFlow`: New command to remove all Salvus managed files from a remote\n  site.\n- `SalvusFlow`: Added API and CLI function to cancel all running jobs on a\n  given site.\n- `General`: Punted copyright and what not years to 2020.\n- `SalvusProject`: Sources and receivers as well as volume, bathymetry, and\n  topography and the data processing functions are now checked for\n  compatibility with the domain before being added to the project.\n- `SalvusFlow`: Allow sites with `max_ranks` set to 1.\n- `SalvusProject`: Added simple test that the project can be relocated and\n  still function properly.\n- `SalvusProject`: Get Salvus input file for a simulation configuration.\n- `SalvusFlow`: Ability to recover from ProxyCommand failures which for some\n  reason also always seem to happen on `KeyboardInterrupt` exceptions.\n- `SalvusProject`: Check if models (of any type) exist in the project at the\n  time a simulation configuration object is added.\n- `SalvusProject`: Hashes of all external data files influencing a simulation\n  are now properly included.\n- `SalvusProject`: Located sources and receiver are now buffered greatly\n  speeding up the operation. Especially useful for many simulations on a\n  single mesh.\n- `SalvusProject`: Rename `WaveformSimulationTemplate` to\n  `WaveformSimulationConfiguration`.\n- `SalvusFlow`/`SalvusProject`: Sources and receivers as well as most project\n  configuration objects are now immutable.\n- `SalvusMesh`: More flexible way to determine the data set names in the\n  global topography files.\n- `SalvusProject`: Add validation step that enforce that all topography\n  models in a simulation configuration for a spherical domain are of the same\n  type, e.g. one Moho and one surface topography but not two or more of each.\n- `SalvusOpt`: Fix CMake dependency and parallel tests\n- `CI`: Check code coverage and manually enforce a threshold\n- `SalvusCompute`: Consistent naming conventions in schema.\n- `SalvusFlow`: Fix init-site after schema changes.\n- `SalvusFlow`: Add simplified smoothing interface.\n- `SalvusOpt`: Polishing the smoothing interface a bit.\n- `SalvusCompute`: Fix error handling for invalid material coefficients\n- `SalvusMesh`: Fix handling of fluid regions for absorbing BCs\n- `SalvusCompute`: Anisotropic smoothing on spherical and cartesian domains.\n- `SalvusProject`: Ability to compare model data from files and in-memory\n  data sets.\n- `SalvusFlow`: Redid the collections and add a low level misfit interface.\n- `SalvusProject`: Project can compute and manage gradients.\n- `SalvusProject`: Proper misfit handling in project.\n- `Meta`: Nicer logging interface for all of SalvusPy.\n- `SalvusProject`: Custom processing functions.\n- `SalvusProject`: Most things can now be optionally overwritten upon adding\n  them a project.\n- `Meta`: Fix a few type hints\n- `SalvusFlow`: Add utility to recreate simple config simulation objects from\n  dictionaries and improve remote file handling\n- `Meta`: Fix broken integration tests and enforce that they are always run\n  on main branches\n- `SalvusPy`: Remove obsolete restrictions on numpy and pyproj\n- `SalvusProject`: Fixing deploy issue with salvus.project.utils\n- `SalvusProject`: Add optimally distributed events from a catalog file.\n- `SalvusProject`: Fix equality operator for the simulation configuration\n  in the case of differing waveform simulation configurations.\n- `SalvusCompute`: Fix sampling rate handling for adjoint runs\n- `SalvusProject`: Bug fixes trace interpolation and handling failed jobs.\n- `Meta`: Use DAG to speedup the CI\n- `Meta`: Update the way the documentation for the website is built.\n- `SalvusProject`: Improve error message and querying data\n- `SalvusCompute`: Fix missing attributes in model write\n- `Provenance`: Include Salvus version number in all output files\n- `SalvusFlow`: Allow `\"SITE_NAME:...\"` remote file in the waveform\n  simulation `simple_config` helper objects.\n- `SalvusFlow`: Now raises a proper error message if one tries to add side\n  set sources/receivers to a waveform simulation object without a locally a\n  available mesh.\n- `SalvusFEM`: Use the `-ffast-math` compile flag in the SalvusFEM Python\n  bindings. Much faster on Linux.\n- `SalvusOpt`: Fix diffusion model in anisotropic smoothing\n- `Meta`: Removed bqplot and bottleneck dependency. The first is not used any\n  more at all. The second only implicitly.\n- `SalvusCompute`: Bug fixes in wavefield container\n- `SalvusFlow` : Bug fix trace interpolation\n- `SalvusFlow`: Delete existing file upon before overwriting in\n  `SalvusJob.copy_output()`. This solves an issue with open HDF5 files.\n- `SalvusCompute`: Rename output field name mass-matrix -> inverse-mass-matrix\n- `CI`: Reorg Instaseis benchmarks\n- `SalvusPy`: Version number check should no longer deadlock + a few other\n  fixes.\n\n## maintenance_0.10 dev\n\n- `Meta`: Clean-up python dependencies and conda envs\n\n## 0.10.11\n\n- `SalvusProblem`: Fix accuracy in l2gmapping for large serial meshes.\n- `Meta`: Move cmakelists.txt inside the repo and add catch\n- `SalvusFlow`: Fix doc strings and small bug in plotting stfs\n\n## 0.10.10\n\n- `SalvusCompute`: Update PETSc API for new PETSc version\n- `SalvusFlow`: Enforce bash in all remote commands to support native csh\"\n- `SalvusFlow`: Some cluster prevent `SSH_FXP_STAT` - there are now alternative\n  `ssh` calls to enable the same functionality in the case of failure.\n- `SalvusFlow`: PBS can now interpolate some variables into qsub and pbsrun\n  arguments.\n- `SalvusFlow`: Optionally set the environment variables inside the submit\n  script.\n\n## 0.10.9\n\n- `General`: Explicitly add the Security framework to the Python packages\n  linking flags on OSX in attempt to make it compatible with old OSX versions.\n- `General`: Add validation stage to ensure proper linking\n\n## 0.10.8\n\n- `SalvusMesh`: Added a cylindrical mode to\n  `UnstructuredMesh.change_tensor_order()`. Please note that the interface of\n  the function also changed.\n- `SalvusMesh`: The `UnstructuredMesh.add_dem_3D()` method now accepts\n  negative infinity as an argument to `z0` which will stretch all points\n  beneath the DEM.\n- `SalvusMesh`: New `StructuredGrid2D.rectangle_xy()` method.\n- `SalvusCompute`: Enforce Courant number in wave equation schema.\n- `General`: Clean up the install requirements in the `setup.py` files.\n- `SalvusCompute` and `SalvusFlow`: Added `Ricker1stDerivative` and\n  `Ricker2ndDerivative` source time functions.\n- `SalvusCompute`: Added field `stress` and `stress-tensor` to point output\n  fields.\n\n## 0.10.7\n\n- `SalvusFlow`: Enforce absolute paths in input files generated by SalvusFlow\n\n## 0.10.6\n\n- `SalvusCompute`: Added the ability to use `scalar_gradient` sources from\n  HDF5 Block Sources\n\n## 0.10.5\n\n_September 30 2019_\n\n- `CI`: enforce modified change log for all MR to maint or master\n- `SalvusFlow+SalvusMesh`: Some mypy updates.\n- `SalvusFlow`: Be more resilient against databases in an inconsistent state.\n- `SalvusFlow`: `salvus_flow.functions.run_many(..., overwrite=True()` now works\n  as expected.\n- `SalvusFlow`: Fancy docstrings for source time functions.\n- `SalvusCompute`: Bug fix for outputting mass matrix in coupled media\n- `SalvusCompute`: Consistent handling of hdf5 point and block sources\n\n## 0.10.4\n\n_September 22 2019_\n\n- `SalvusCompute`: Optional rotation matrix for source input\n- `SalvusCompute`: Support for 1D wavelets as custom sources\n- `SalvusCompute`: Bug-fix anisotropic coupled simulations\n- `SalvusFlow`: Significantly improved interface for custom source time functions\n- `SalvusFlow`: Built-in support of filtered Heaviside stf\n- `SalvusMesh`: Type hints and doc strings\n\n## 0.9.x\n\n_Unreleased_\n\n- `SalvusMesh`: Cleaner way to interpolate models on high-order meshes.\n- `SalvusFlow`: More stable source/receiver placement.\n\n## 0.9.1\n\n_April 30 2019_\n\n- `SalvusCompute`: Fix surface output.\n\n## 0.9.0\n\n_April 26 2019_\n\n- `SalvusCompute`: Support for TTI media.\n- `SalvusCompute`: Reworked sources.\n- `SalvusFlow`: Reworked the simple config to have a cleaner hierarchy.\n- `SalvusFlow`: Ability to place sources and receivers on arbitrary meshes.\n- `SalvusFlow`: Seismological source and receiver output.\n- `SalvusCompute` & `SalvusFlow`: Rotate receiver output.\\\n\"\"\"\n"}}}]}}}