diff --git a/.git-rewrite/.msys0000000000013e5810efbf8460c46dfb b/.git-rewrite/.msys0000000000013e5810efbf8460c46dfb new file mode 100644 index 0000000..6cc282b --- /dev/null +++ b/.git-rewrite/.msys0000000000013e5810efbf8460c46dfb @@ -0,0 +1,480 @@ +60fd1e4e5283582d553099f579fb7cfee5c06dfc +fc0adab03f12a2679d99ade85192ebed295b61df 60fd1e4e5283582d553099f579fb7cfee5c06dfc +fa3aa2d433dce5fef286c0125e469e51ecc74ae4 fc0adab03f12a2679d99ade85192ebed295b61df +00ff197ee4f9c229221e3ea657122ed91e796819 fa3aa2d433dce5fef286c0125e469e51ecc74ae4 +3cfdb3fd6adccf2e46baf241ea4313f12aabeed5 fa3aa2d433dce5fef286c0125e469e51ecc74ae4 00ff197ee4f9c229221e3ea657122ed91e796819 +c1e53e0bcb50fdd68592cba68b5aa1ec13e074bf fa3aa2d433dce5fef286c0125e469e51ecc74ae4 +95ae4887a8cdd80ce5531fdd286d39ee8f8f673e 3cfdb3fd6adccf2e46baf241ea4313f12aabeed5 c1e53e0bcb50fdd68592cba68b5aa1ec13e074bf +e2b08b3091970d15c62be88fe4a09b4d048c8e18 95ae4887a8cdd80ce5531fdd286d39ee8f8f673e +c688039dbef9723b269088f5ef55747a97e7e92b e2b08b3091970d15c62be88fe4a09b4d048c8e18 +f9fad28c27b010e3f1e66ed779062f4e7da4c7fb 95ae4887a8cdd80ce5531fdd286d39ee8f8f673e c688039dbef9723b269088f5ef55747a97e7e92b +59690cd034bf65702a006c99ca0553349c15a16c fa3aa2d433dce5fef286c0125e469e51ecc74ae4 +d31d65343d022de9270313b6052cf262c78929a7 f9fad28c27b010e3f1e66ed779062f4e7da4c7fb 59690cd034bf65702a006c99ca0553349c15a16c +01109e45910e81da74b56eff9035bd1696bec8ba d31d65343d022de9270313b6052cf262c78929a7 +e812cd697e3cdf2e6404397339b348e28afc225c d31d65343d022de9270313b6052cf262c78929a7 01109e45910e81da74b56eff9035bd1696bec8ba +ce2deb0d5fd024ee34c522ddb65748c7ad4dfaee d31d65343d022de9270313b6052cf262c78929a7 +c8aa1dae0558a781cf350a1e4e89810083000848 ce2deb0d5fd024ee34c522ddb65748c7ad4dfaee +04cacc7f1cf78b0c3b459cb86f884c560b79f2c6 e812cd697e3cdf2e6404397339b348e28afc225c c8aa1dae0558a781cf350a1e4e89810083000848 +cde2162f678c28c94b92e508cbd6347ac50712a9 04cacc7f1cf78b0c3b459cb86f884c560b79f2c6 +bf761fa286abd0588c0af17777b53a62304ea0f5 04cacc7f1cf78b0c3b459cb86f884c560b79f2c6 cde2162f678c28c94b92e508cbd6347ac50712a9 +d5420e5960fa3ebe77462738f370be90a59d6bfb 04cacc7f1cf78b0c3b459cb86f884c560b79f2c6 +4278ad016b22e4502267f355ed385fe1d340099c bf761fa286abd0588c0af17777b53a62304ea0f5 d5420e5960fa3ebe77462738f370be90a59d6bfb +7b732f65ef8eacd7d9118c01f8d82b3afe6534b8 4278ad016b22e4502267f355ed385fe1d340099c +6aa5a9ecf8065a178a64afcba634d09e1b7c11c4 4278ad016b22e4502267f355ed385fe1d340099c 7b732f65ef8eacd7d9118c01f8d82b3afe6534b8 +b6f7665dc88bff839141eab78aa8d6c5aa600a99 6aa5a9ecf8065a178a64afcba634d09e1b7c11c4 +f524d1412370b2ae697aa584c30267cef67d2a01 6aa5a9ecf8065a178a64afcba634d09e1b7c11c4 b6f7665dc88bff839141eab78aa8d6c5aa600a99 +668d3321d3df9a1b34d71d408c38f04d0933f368 f524d1412370b2ae697aa584c30267cef67d2a01 +15a1c6f6e60b426cea79e938fd8f504c76063a11 668d3321d3df9a1b34d71d408c38f04d0933f368 +6a52793fdcfe6e52d0b9d31122793ce6dc09b8fc f524d1412370b2ae697aa584c30267cef67d2a01 15a1c6f6e60b426cea79e938fd8f504c76063a11 +6bdf87f0b5ea9150c6c8db57ceeca6138e820c80 6a52793fdcfe6e52d0b9d31122793ce6dc09b8fc +502d052829d07365c9df8ca5d686c6369bad3eae 6a52793fdcfe6e52d0b9d31122793ce6dc09b8fc 6bdf87f0b5ea9150c6c8db57ceeca6138e820c80 +68ae6364467c8ab8fdabd9a1089a608dedb02830 502d052829d07365c9df8ca5d686c6369bad3eae +84d914bf6efbfd7a3e25f53013cbdb9bfa65f320 68ae6364467c8ab8fdabd9a1089a608dedb02830 +93ec2e061775a89972684b860cb94916585e0caa 84d914bf6efbfd7a3e25f53013cbdb9bfa65f320 +1e2d93fbcb79de1ed2623a396b09f78ccef6fb02 93ec2e061775a89972684b860cb94916585e0caa +dfb19cc17586bb0cdcb97516cd7861c57780281f 1e2d93fbcb79de1ed2623a396b09f78ccef6fb02 +5988afade57a127425bf8ede7d07fece2f9dc248 dfb19cc17586bb0cdcb97516cd7861c57780281f +82bf36a64a4c2924815b3d2468b4bceae24cc57b 5988afade57a127425bf8ede7d07fece2f9dc248 +111342571efefa9e0a7ab030d14db3a865a20e0b 82bf36a64a4c2924815b3d2468b4bceae24cc57b +d3a51bd1c50f4762739d17c3126e8534994ed6ee 111342571efefa9e0a7ab030d14db3a865a20e0b +be83642e9f90a74b3c7b9a29eb015840114abaaa d3a51bd1c50f4762739d17c3126e8534994ed6ee +880b616d977f92f3712daeec7d2426a203802979 be83642e9f90a74b3c7b9a29eb015840114abaaa +a4114e32538564eb21110bc0c9caeed74cb75971 880b616d977f92f3712daeec7d2426a203802979 +b460c15616a1b04b263a8e11dce998f5bf3b95e8 502d052829d07365c9df8ca5d686c6369bad3eae a4114e32538564eb21110bc0c9caeed74cb75971 +53ba06cce71ed5c2c32f7593338ba9016db8fd0d b460c15616a1b04b263a8e11dce998f5bf3b95e8 +0a3b9ac02c8c089781f5f5c61771d550ceea824e 53ba06cce71ed5c2c32f7593338ba9016db8fd0d +ff24de1ffee632d277aab2afde423b815f15f08d 0a3b9ac02c8c089781f5f5c61771d550ceea824e +d00972dbc62f61914326d93b9ad371762452ef0f b460c15616a1b04b263a8e11dce998f5bf3b95e8 ff24de1ffee632d277aab2afde423b815f15f08d +3a5fb2bfea011fb99dc41b1f1ea3d5b9a362007f b460c15616a1b04b263a8e11dce998f5bf3b95e8 +e5afe1eef207816550d7d9ce63b4c3e5206537c8 d00972dbc62f61914326d93b9ad371762452ef0f 3a5fb2bfea011fb99dc41b1f1ea3d5b9a362007f +08c6c4a922ab8a201b686e99fca9b1f44f0ab2f8 e5afe1eef207816550d7d9ce63b4c3e5206537c8 +6f8a9cc1d538c3ffef93a82a6df87b2fe767369d e5afe1eef207816550d7d9ce63b4c3e5206537c8 08c6c4a922ab8a201b686e99fca9b1f44f0ab2f8 +fd96634d6b6a388f12c3c07f177ea3561ea4f965 6f8a9cc1d538c3ffef93a82a6df87b2fe767369d +e8196c83db18486f02b8f7df90e1dbfad929f699 6f8a9cc1d538c3ffef93a82a6df87b2fe767369d fd96634d6b6a388f12c3c07f177ea3561ea4f965 +8a67814b0146daa725e4c52a7210ab8f51004249 6f8a9cc1d538c3ffef93a82a6df87b2fe767369d +bb8fc5d212c0f9150c0b33cd05ec8416ca05363d e8196c83db18486f02b8f7df90e1dbfad929f699 8a67814b0146daa725e4c52a7210ab8f51004249 +f6dda84184442380f32f05fb3709b530fb1958a0 bb8fc5d212c0f9150c0b33cd05ec8416ca05363d +0afcc54f923625def27f751d40fe6a68829ba7cb bb8fc5d212c0f9150c0b33cd05ec8416ca05363d f6dda84184442380f32f05fb3709b530fb1958a0 +117ada35cd9c75f3163eea61b9f885884be37050 6f8a9cc1d538c3ffef93a82a6df87b2fe767369d +2567f766f132f2c33e535ad2ff3184ea613ebc10 0afcc54f923625def27f751d40fe6a68829ba7cb 117ada35cd9c75f3163eea61b9f885884be37050 +ef0ba9f84a32e6b7af467a141383052fa7b673c5 6f8a9cc1d538c3ffef93a82a6df87b2fe767369d +518d78604a042e393e0c33bf5d473c541fb6b93e 2567f766f132f2c33e535ad2ff3184ea613ebc10 ef0ba9f84a32e6b7af467a141383052fa7b673c5 +93a0c28570021d5ea04dae9b10287de42b96cf5a 6f8a9cc1d538c3ffef93a82a6df87b2fe767369d +dbbe26a11c952d78aa31e5385905ac904e1bd700 518d78604a042e393e0c33bf5d473c541fb6b93e 93a0c28570021d5ea04dae9b10287de42b96cf5a +d6151e1de60596eb8f0ca515cca734e8eaebac95 dbbe26a11c952d78aa31e5385905ac904e1bd700 +3cda3b59eebf8183bfe22d0056a486049d5f8ea7 dbbe26a11c952d78aa31e5385905ac904e1bd700 d6151e1de60596eb8f0ca515cca734e8eaebac95 +35fae746972e901190a3b4962c9caa26635b7eb3 dbbe26a11c952d78aa31e5385905ac904e1bd700 +492ce1f5cec5e0144e4c67f40b707dee5dfa7067 3cda3b59eebf8183bfe22d0056a486049d5f8ea7 35fae746972e901190a3b4962c9caa26635b7eb3 +a3ce95fe3c1cc0ef270ee4e319f6f6f46cd4ce27 492ce1f5cec5e0144e4c67f40b707dee5dfa7067 +f3c52c18ad9965c462c8f6c999eb6020925ea94b 492ce1f5cec5e0144e4c67f40b707dee5dfa7067 a3ce95fe3c1cc0ef270ee4e319f6f6f46cd4ce27 +1ec93db595eac829fc6141def47abf34b40a9a06 f3c52c18ad9965c462c8f6c999eb6020925ea94b +8278b2d6742ae79560e1cfa747739a44a8b75ccf f3c52c18ad9965c462c8f6c999eb6020925ea94b 1ec93db595eac829fc6141def47abf34b40a9a06 +28c4b358e05aedc8aa9735d157cf94c53175aa7f f3c52c18ad9965c462c8f6c999eb6020925ea94b +17abdae01e3e4c8433659f6d12246496bde1a81f 8278b2d6742ae79560e1cfa747739a44a8b75ccf 28c4b358e05aedc8aa9735d157cf94c53175aa7f +ccffac4525e124d329a0f2638bc08a36d23d4394 8278b2d6742ae79560e1cfa747739a44a8b75ccf +46c15c96f582a3fd2873cd656cead5d9fba0d7d6 17abdae01e3e4c8433659f6d12246496bde1a81f ccffac4525e124d329a0f2638bc08a36d23d4394 +dddb73c327bac400145fbc94c31bd83415709fe7 f3c52c18ad9965c462c8f6c999eb6020925ea94b +628892bbc735155e540d95940047f41d677eadfa 46c15c96f582a3fd2873cd656cead5d9fba0d7d6 dddb73c327bac400145fbc94c31bd83415709fe7 +8a07f6f0966a32dcc4789af167738c72d37e6c28 628892bbc735155e540d95940047f41d677eadfa +5d659cea06722079dcb1542f0808bad65e13f005 628892bbc735155e540d95940047f41d677eadfa 8a07f6f0966a32dcc4789af167738c72d37e6c28 +aba1d8975b634c1d597ba54443e422714475b5cd 5d659cea06722079dcb1542f0808bad65e13f005 +65e57958ce47ca064e3443bb74895453cc8e1807 aba1d8975b634c1d597ba54443e422714475b5cd +7ec2f1a997d4a5c994fb5fb485b2d41474c573c8 65e57958ce47ca064e3443bb74895453cc8e1807 +1876ada0b2dd5c05bc5d90b8eedd93a4248b87f8 7ec2f1a997d4a5c994fb5fb485b2d41474c573c8 +7a36ff737f7f863d5b62e46ad2b20acd26d00ee0 1876ada0b2dd5c05bc5d90b8eedd93a4248b87f8 +1dbf231779dea6e3b985cdd40544e41538b96092 7a36ff737f7f863d5b62e46ad2b20acd26d00ee0 +431fdc4e5c7551e4b7a39e0c5f3c6d03c0300315 1dbf231779dea6e3b985cdd40544e41538b96092 +97ab1a6aa8e25ad5ba7e0711fe186d780fef509e 431fdc4e5c7551e4b7a39e0c5f3c6d03c0300315 +091c23171030fccdc9344097791c5fc46b369986 97ab1a6aa8e25ad5ba7e0711fe186d780fef509e +6c2821259f82765c898f37bea7ff3e9f5aa27b2c 091c23171030fccdc9344097791c5fc46b369986 +b39d57dd8b33309768dcb4422ed486ecb9e08703 6c2821259f82765c898f37bea7ff3e9f5aa27b2c +1d26d7e7c906d80f82c15c3a003b6fd08ee82f0d b39d57dd8b33309768dcb4422ed486ecb9e08703 +86b47783fa80e00d80238f46767affc9cc3f42f3 1d26d7e7c906d80f82c15c3a003b6fd08ee82f0d +619729fd95d5b1628c3c511de7576724a2edbfdb 86b47783fa80e00d80238f46767affc9cc3f42f3 +2ba385b3fc71bd2da2f19abc1da8397c94ab7054 619729fd95d5b1628c3c511de7576724a2edbfdb +7474e762272dde4dfa2383cbdeb162d29a46e944 2ba385b3fc71bd2da2f19abc1da8397c94ab7054 +2104d2986de468b215fe071325892097ef89de34 7474e762272dde4dfa2383cbdeb162d29a46e944 +afc853e592346d341ea33fd9944c6d38ab258f1d 2104d2986de468b215fe071325892097ef89de34 +24c8396130d102bbdd750a48f4765691529fbc79 afc853e592346d341ea33fd9944c6d38ab258f1d +a1de7f1c487911218324cf13802e82b4e2bb13f1 24c8396130d102bbdd750a48f4765691529fbc79 +8f875ccb1cb9350d61a96a1b712297774bad3cd8 a1de7f1c487911218324cf13802e82b4e2bb13f1 +925bbcdb363cde43d80475174389bdbfe3a938db 8f875ccb1cb9350d61a96a1b712297774bad3cd8 +ac2f0510ab4b042b62d650ecf0199977966824bd 925bbcdb363cde43d80475174389bdbfe3a938db +7a0c8de6f1e98c697929555221221b86f1a42fd1 ac2f0510ab4b042b62d650ecf0199977966824bd +730896f658bf8c6a881bbf9dc14d2a5e1666a995 7a0c8de6f1e98c697929555221221b86f1a42fd1 +4a6c8eb89d38f964bea3f93a592a678351c813bf 730896f658bf8c6a881bbf9dc14d2a5e1666a995 +342c6379e299b7248f928fa0113beca1af85d935 5d659cea06722079dcb1542f0808bad65e13f005 4a6c8eb89d38f964bea3f93a592a678351c813bf +c957190fd91539904eb352dc197fef1f244ff84f 342c6379e299b7248f928fa0113beca1af85d935 +b5534d2dd26000be4c04ef89924084cb3cf857bb c957190fd91539904eb352dc197fef1f244ff84f +a6f4f064c3f23d892a48636ed98fae1aa4305b15 b5534d2dd26000be4c04ef89924084cb3cf857bb +50fbdf6c0a0a10e2f04b11d51162bb2eb8221f70 342c6379e299b7248f928fa0113beca1af85d935 a6f4f064c3f23d892a48636ed98fae1aa4305b15 +3c7d91d2e68f0080f141b6e334760733b28b319c 50fbdf6c0a0a10e2f04b11d51162bb2eb8221f70 +bf898a3e584cbc662ab4cc331efc23d2e494b24c 3c7d91d2e68f0080f141b6e334760733b28b319c +65e1df833d7eabd0ce66efbc4dafb982341f6c77 50fbdf6c0a0a10e2f04b11d51162bb2eb8221f70 bf898a3e584cbc662ab4cc331efc23d2e494b24c +2be03062b506c8dbcae996e8d523cd116ff58313 65e1df833d7eabd0ce66efbc4dafb982341f6c77 +b43a96291898f24e2240889708379f110f5d9110 65e1df833d7eabd0ce66efbc4dafb982341f6c77 2be03062b506c8dbcae996e8d523cd116ff58313 +0c1fcc8375668108d852b27dafce2ed89a510429 b43a96291898f24e2240889708379f110f5d9110 +d50c9d2224da58f5f3c32931e44a161a94bf6971 0c1fcc8375668108d852b27dafce2ed89a510429 +a77f8b51dba795cd2908f7b7b0b2c3a7f8a17ea6 b43a96291898f24e2240889708379f110f5d9110 d50c9d2224da58f5f3c32931e44a161a94bf6971 +6e63469e3334afa3fbe2f2f7883d9ad895a16608 a77f8b51dba795cd2908f7b7b0b2c3a7f8a17ea6 +2f24aedcf903e6b6adb02154b2a034a8a1b8e31b a77f8b51dba795cd2908f7b7b0b2c3a7f8a17ea6 6e63469e3334afa3fbe2f2f7883d9ad895a16608 +5058e605337c285e6dff4706ad919086df6fa9f9 65e1df833d7eabd0ce66efbc4dafb982341f6c77 +405c0f3b82d4cfb0eb5ae7240ffd5c216edd0495 5058e605337c285e6dff4706ad919086df6fa9f9 +0070b24402b7f0295b6805a33a2bab11f9f06077 405c0f3b82d4cfb0eb5ae7240ffd5c216edd0495 +c5dd0edc7216ea026a8a76259d24f4f0799854dd 2f24aedcf903e6b6adb02154b2a034a8a1b8e31b 0070b24402b7f0295b6805a33a2bab11f9f06077 +26a0b4ad639b7e5c202931a604fa8d4622f15a58 c5dd0edc7216ea026a8a76259d24f4f0799854dd +6951b28e1b4893e48dd0b337f91c78a9bb9d5c05 c5dd0edc7216ea026a8a76259d24f4f0799854dd 26a0b4ad639b7e5c202931a604fa8d4622f15a58 +b0b861ebb74d131f809e7e7fa10987b9b1337548 c5dd0edc7216ea026a8a76259d24f4f0799854dd +93107e900b45f3bd5caf9298e63994de288c1d86 6951b28e1b4893e48dd0b337f91c78a9bb9d5c05 b0b861ebb74d131f809e7e7fa10987b9b1337548 +6cb00ec67b184f73ce548f184e0a3fca0095cce1 c5dd0edc7216ea026a8a76259d24f4f0799854dd +4a27b337b474162b6530b5dbe2d3ea6906b49947 93107e900b45f3bd5caf9298e63994de288c1d86 6cb00ec67b184f73ce548f184e0a3fca0095cce1 +62cb99e34e84f5bd668c248e04438ef4eb2e45bd 4a27b337b474162b6530b5dbe2d3ea6906b49947 +d896b9785e80fc9052188fd0c032eb049389a627 4a27b337b474162b6530b5dbe2d3ea6906b49947 62cb99e34e84f5bd668c248e04438ef4eb2e45bd +d3aa6b54e6d8f82f5115dc826e13a72a3ffc373d 4a27b337b474162b6530b5dbe2d3ea6906b49947 +8568f86f02caf8dd773658650347306b3b05cca8 d896b9785e80fc9052188fd0c032eb049389a627 d3aa6b54e6d8f82f5115dc826e13a72a3ffc373d +3307ded21ee741318d7f803123b038459ff8728b 8568f86f02caf8dd773658650347306b3b05cca8 +f12c233d19015f982cdceb293426870d62ae7df3 8568f86f02caf8dd773658650347306b3b05cca8 3307ded21ee741318d7f803123b038459ff8728b +8ea1cba7901acdfca84b2903535b383559cdbefe f12c233d19015f982cdceb293426870d62ae7df3 +014cc81e7425741938f0d059a49992ce3b00cd4d 8ea1cba7901acdfca84b2903535b383559cdbefe +63faea9aa74b4207d7ed08d9f0ca2168ade7d5b1 014cc81e7425741938f0d059a49992ce3b00cd4d +6b46ded74dd2cf8d9d181779c9587887d1745eab f12c233d19015f982cdceb293426870d62ae7df3 63faea9aa74b4207d7ed08d9f0ca2168ade7d5b1 +002044053bc9709aa480b0ca60b3ba1c996103f4 6b46ded74dd2cf8d9d181779c9587887d1745eab +3e3e351dd30ce1ae84fd045fc288b968c8eff9cf 6b46ded74dd2cf8d9d181779c9587887d1745eab 002044053bc9709aa480b0ca60b3ba1c996103f4 +d831a3901e510510a4d2cbd57c1f164ace398968 6b46ded74dd2cf8d9d181779c9587887d1745eab +20883a877e7f2a749b9ea86f421aff63c4206547 3e3e351dd30ce1ae84fd045fc288b968c8eff9cf d831a3901e510510a4d2cbd57c1f164ace398968 +733f63064504e7967e9f7ad1e7d14164b621c192 6b46ded74dd2cf8d9d181779c9587887d1745eab +fe8bd80aec898d52f95226316f45023ee05ddb28 733f63064504e7967e9f7ad1e7d14164b621c192 +964b17969031591fb2cfaf57e8f97360e524d88a fe8bd80aec898d52f95226316f45023ee05ddb28 +f87df69c93fcc06e61beb220d49aaf86c484fda7 20883a877e7f2a749b9ea86f421aff63c4206547 964b17969031591fb2cfaf57e8f97360e524d88a +3cafe85d26c7bc55b2c5ac6a8359d5a7554c178a 20883a877e7f2a749b9ea86f421aff63c4206547 +779863aa59436f04b1b128993f73428261951b79 3cafe85d26c7bc55b2c5ac6a8359d5a7554c178a +8caf511a20c4b8700900c3086d160dc40b1c45d0 f87df69c93fcc06e61beb220d49aaf86c484fda7 779863aa59436f04b1b128993f73428261951b79 +766615b564b4eb9d46a00c2d4558e5c4a0d0c3bc 8caf511a20c4b8700900c3086d160dc40b1c45d0 +11f70d957dd0dce4b31b345638594c8d08557ba6 8caf511a20c4b8700900c3086d160dc40b1c45d0 766615b564b4eb9d46a00c2d4558e5c4a0d0c3bc +e43dd64b669b3712ee3e898f4c340b81a7c3d1b3 11f70d957dd0dce4b31b345638594c8d08557ba6 +c832a061acdf8266f9de8e9c76cec21a573b9282 e43dd64b669b3712ee3e898f4c340b81a7c3d1b3 +b82923a1c30e2b1995b0699f264ccdb0f7c48e1e 11f70d957dd0dce4b31b345638594c8d08557ba6 c832a061acdf8266f9de8e9c76cec21a573b9282 +cddb78334eb8fb67f64dbf400ac53f519c7ff053 b82923a1c30e2b1995b0699f264ccdb0f7c48e1e +a655f7e2e7ce63127e866978bb6c0057ce68007e b82923a1c30e2b1995b0699f264ccdb0f7c48e1e cddb78334eb8fb67f64dbf400ac53f519c7ff053 +78a5172f8ff90ddad9908288020b29ab88036f88 a655f7e2e7ce63127e866978bb6c0057ce68007e +e2c2adffacc67111b357fff2d2e79463d6e445a3 a655f7e2e7ce63127e866978bb6c0057ce68007e 78a5172f8ff90ddad9908288020b29ab88036f88 +37a7f901398beae61e0678c12823b53e60320fcc e2c2adffacc67111b357fff2d2e79463d6e445a3 +506a5b9d3b21123bf4414843405482b7ad8ed2c2 37a7f901398beae61e0678c12823b53e60320fcc +844306ae3a6f2860aa4a8e85a6d8a96139e267d2 506a5b9d3b21123bf4414843405482b7ad8ed2c2 +07b18670399b58d89dbef41025dcc3157cf64dd4 e2c2adffacc67111b357fff2d2e79463d6e445a3 844306ae3a6f2860aa4a8e85a6d8a96139e267d2 +4817063fea882d8f72eb0f84bb853b8833820cc0 e2c2adffacc67111b357fff2d2e79463d6e445a3 +a7677351be8079171156e166a313b4813e6e0a1c 07b18670399b58d89dbef41025dcc3157cf64dd4 4817063fea882d8f72eb0f84bb853b8833820cc0 +b7404650b11593f347a7e15f80912679203bd7d1 a7677351be8079171156e166a313b4813e6e0a1c +eaa0ce29ad50e010c3cc17205a16a4e6e2a4f2c4 b7404650b11593f347a7e15f80912679203bd7d1 +1ca70d8f7dfb2f75f8e9a54ecd9a7c233cd26561 a7677351be8079171156e166a313b4813e6e0a1c eaa0ce29ad50e010c3cc17205a16a4e6e2a4f2c4 +a44ddf2f04e2bf053f04b711831b12ae6d11a674 1ca70d8f7dfb2f75f8e9a54ecd9a7c233cd26561 +ba3f9405c7a3c684474128ddba882ec091b8f2e7 1ca70d8f7dfb2f75f8e9a54ecd9a7c233cd26561 a44ddf2f04e2bf053f04b711831b12ae6d11a674 +38eea78433401c1e0d2a5e69154a01e655ba05a0 ba3f9405c7a3c684474128ddba882ec091b8f2e7 +707152cd4dd61f35c51ab81e4c9c687e1a2c84b2 ba3f9405c7a3c684474128ddba882ec091b8f2e7 38eea78433401c1e0d2a5e69154a01e655ba05a0 +b7b9e79f219ed2295816f41cd92aeb79a9e3eccd 707152cd4dd61f35c51ab81e4c9c687e1a2c84b2 +fc94efe10f2c9705a2f89747c8d5726ee46eba61 707152cd4dd61f35c51ab81e4c9c687e1a2c84b2 b7b9e79f219ed2295816f41cd92aeb79a9e3eccd +83452ec8d8a49890ef85e3d3476f7ad95500c57e fc94efe10f2c9705a2f89747c8d5726ee46eba61 +1f9af0c24bb605d2cc119218b1a55fce63f197bd fc94efe10f2c9705a2f89747c8d5726ee46eba61 83452ec8d8a49890ef85e3d3476f7ad95500c57e +9952adeea5b14a2ec01821052b1ff5782d9cad3f 707152cd4dd61f35c51ab81e4c9c687e1a2c84b2 +d72025979d95e65771aa88afd9ff4d8f0c8d69b5 1f9af0c24bb605d2cc119218b1a55fce63f197bd 9952adeea5b14a2ec01821052b1ff5782d9cad3f +0f680afc07271eb585aae571b3fbdfeb0d8bd049 d72025979d95e65771aa88afd9ff4d8f0c8d69b5 +b18ae98f20e524351fb8e93ba4afa6610606ff8f 0f680afc07271eb585aae571b3fbdfeb0d8bd049 +f7df94a632b36b987906d9da85c2a14e3f00b124 d72025979d95e65771aa88afd9ff4d8f0c8d69b5 b18ae98f20e524351fb8e93ba4afa6610606ff8f +c7a21b0ff708462fc0d13d89331195f903e6673d f7df94a632b36b987906d9da85c2a14e3f00b124 +c6ca63081ca7f5a39c1d266337334648393f1a1a c7a21b0ff708462fc0d13d89331195f903e6673d +617da5c2945c86199b42623c66dbe242f6b205fa c6ca63081ca7f5a39c1d266337334648393f1a1a +cb3dfd9047ce77d87d6a15368d08d9b7167d60c1 617da5c2945c86199b42623c66dbe242f6b205fa +412cf6177802995200a2ea6f8a99a36c7785f70e cb3dfd9047ce77d87d6a15368d08d9b7167d60c1 +fb6f642687e62a7c90d99889a99cbdd51909c9e5 412cf6177802995200a2ea6f8a99a36c7785f70e +3b774c47abd63cf5461a56272212553da693b54b fb6f642687e62a7c90d99889a99cbdd51909c9e5 +11f279d5dd639ed03ea8bf4423ffe2f185ddfb01 3b774c47abd63cf5461a56272212553da693b54b +85cfa2aa2e82db7c624ce9af846978e5b6790c11 11f279d5dd639ed03ea8bf4423ffe2f185ddfb01 +f044aaa082cbb79fc1db8d125f5010b9c4ba57fb f7df94a632b36b987906d9da85c2a14e3f00b124 85cfa2aa2e82db7c624ce9af846978e5b6790c11 +25d22437a7e1da47e2e79c74525109b97ea8334e f044aaa082cbb79fc1db8d125f5010b9c4ba57fb +0a18f84e0423724ca76900cc1dfea9d546285e38 f044aaa082cbb79fc1db8d125f5010b9c4ba57fb 25d22437a7e1da47e2e79c74525109b97ea8334e +ae90311e4142ff6f80713ee939a8724f503c78e8 f044aaa082cbb79fc1db8d125f5010b9c4ba57fb +5ce5a6808d78304345d982204193ce34cf14db21 ae90311e4142ff6f80713ee939a8724f503c78e8 +5201e60ecc4bae162536811ba4b45eafd30030c9 0a18f84e0423724ca76900cc1dfea9d546285e38 5ce5a6808d78304345d982204193ce34cf14db21 +dec53d5ad7596decfdc4bb5e1044304380e3389e f044aaa082cbb79fc1db8d125f5010b9c4ba57fb +95a1ed15ee1c456f5164107ad19e6decacff6d83 5201e60ecc4bae162536811ba4b45eafd30030c9 dec53d5ad7596decfdc4bb5e1044304380e3389e +a8bc2d412af19a01e66af03299113f9c189d110c 95a1ed15ee1c456f5164107ad19e6decacff6d83 +3f233874e5e3e4b5967736d7320e8a4c384f6b15 95a1ed15ee1c456f5164107ad19e6decacff6d83 a8bc2d412af19a01e66af03299113f9c189d110c +15b1e4476503b22ac56f8ac554e34c74aa92813e 95a1ed15ee1c456f5164107ad19e6decacff6d83 +e470c7ad9d666f10d34a95c8fa48f6c80b97d644 3f233874e5e3e4b5967736d7320e8a4c384f6b15 15b1e4476503b22ac56f8ac554e34c74aa92813e +c4cfe93fe314a0b42b3b55ed9b6dfabeb9cd76d1 95a1ed15ee1c456f5164107ad19e6decacff6d83 +342178232bdc7eacf7b5cf8eeba2c9e1f10dc559 e470c7ad9d666f10d34a95c8fa48f6c80b97d644 c4cfe93fe314a0b42b3b55ed9b6dfabeb9cd76d1 +8292a9839601eb7bf05a723ef8505739ccace174 95a1ed15ee1c456f5164107ad19e6decacff6d83 +53fdc32f1cdeb30c80c6cf71abf0eb1df0a7e981 342178232bdc7eacf7b5cf8eeba2c9e1f10dc559 8292a9839601eb7bf05a723ef8505739ccace174 +f526d04c6e465bbe692dd44902abf62e9605fdcf 53fdc32f1cdeb30c80c6cf71abf0eb1df0a7e981 +95d04a0a9c18b26836cb725b51c6c27239278bf3 53fdc32f1cdeb30c80c6cf71abf0eb1df0a7e981 f526d04c6e465bbe692dd44902abf62e9605fdcf +04cc47addf7512ebcb54f127ac163aed70ef3c5d 95d04a0a9c18b26836cb725b51c6c27239278bf3 +3b299c4a87155f103b7c3f64828dca51543ef78a 95d04a0a9c18b26836cb725b51c6c27239278bf3 04cc47addf7512ebcb54f127ac163aed70ef3c5d +282d1729aab5ca52f2787be1ce585af9bf3610a7 3b299c4a87155f103b7c3f64828dca51543ef78a +e0db333319aa7e674aed6f4a4e7123bc9f4cde23 282d1729aab5ca52f2787be1ce585af9bf3610a7 +40c7f61aa8f7d5776c6dbcbfbb83ec530bde460a e0db333319aa7e674aed6f4a4e7123bc9f4cde23 +aecd13d01a3d61eb0116bb4b83bd3e482f0f2a2c 282d1729aab5ca52f2787be1ce585af9bf3610a7 40c7f61aa8f7d5776c6dbcbfbb83ec530bde460a +1c68d78862622ac9df00c797c9a7c8c944f0e680 aecd13d01a3d61eb0116bb4b83bd3e482f0f2a2c +4bae4bd30f64eacc0a52e293739abadcdf6767f0 1c68d78862622ac9df00c797c9a7c8c944f0e680 +0d548da4ea164646c6fd84714c921240f9e784b9 1c68d78862622ac9df00c797c9a7c8c944f0e680 4bae4bd30f64eacc0a52e293739abadcdf6767f0 +294df65c31c98f24a3c8fbe5fffefe61285f775a 1c68d78862622ac9df00c797c9a7c8c944f0e680 +71349f4d1b0ab754b9a56c69d75cdebc2c76adcc 294df65c31c98f24a3c8fbe5fffefe61285f775a +d97a56c9d26ef30933cfbb46351c8a800e346e1a 0d548da4ea164646c6fd84714c921240f9e784b9 71349f4d1b0ab754b9a56c69d75cdebc2c76adcc +c59df8123220a184fd8ca407b24988c96d47c62b d97a56c9d26ef30933cfbb46351c8a800e346e1a +f65a7f6fca4957d0ce248c843294ae3e33f1fa32 d97a56c9d26ef30933cfbb46351c8a800e346e1a c59df8123220a184fd8ca407b24988c96d47c62b +d5808e547663772f4946f3440248ed1b7b432aca f65a7f6fca4957d0ce248c843294ae3e33f1fa32 +c37715ef5025a25b7b8d34e4efe357b77de2ce5c f65a7f6fca4957d0ce248c843294ae3e33f1fa32 d5808e547663772f4946f3440248ed1b7b432aca +3bafa3a9fa22a26509c6e2eacaa07e67725c6533 c37715ef5025a25b7b8d34e4efe357b77de2ce5c +d040a8f78af0da128c0aff62bd35dac255b97758 c37715ef5025a25b7b8d34e4efe357b77de2ce5c 3bafa3a9fa22a26509c6e2eacaa07e67725c6533 +5bb655dfccdacc98242d7dee400a8f7ae8bf4bd5 d040a8f78af0da128c0aff62bd35dac255b97758 +74ae02566f412402d9ef672b1cd3221890abc495 5bb655dfccdacc98242d7dee400a8f7ae8bf4bd5 +d6dee1f03d2a1dc1d1af72656e8c017990c40624 74ae02566f412402d9ef672b1cd3221890abc495 +7cc65f2d47a05484a263156fe383fabaca869c53 d6dee1f03d2a1dc1d1af72656e8c017990c40624 +834413799696af7be820d0f3e6667fdf5e298f05 d040a8f78af0da128c0aff62bd35dac255b97758 7cc65f2d47a05484a263156fe383fabaca869c53 +f218d6432722e9c568256c3efda5683facb0f695 834413799696af7be820d0f3e6667fdf5e298f05 +d7dbb20387b3f72ee3c2eeb6e0196024b79e0bc8 f218d6432722e9c568256c3efda5683facb0f695 +1881860521cc6c3beb4fff7b4e73573378ee029e 834413799696af7be820d0f3e6667fdf5e298f05 d7dbb20387b3f72ee3c2eeb6e0196024b79e0bc8 +6db2fa7907557f3b4e148421cce1827f40b7dc7b 1881860521cc6c3beb4fff7b4e73573378ee029e +80a431a3142374cbdea84f69f0d4ad233e587dcd 1881860521cc6c3beb4fff7b4e73573378ee029e 6db2fa7907557f3b4e148421cce1827f40b7dc7b +8135c8e0aaa037fed06cef529024bb542d811778 80a431a3142374cbdea84f69f0d4ad233e587dcd +fdc5596b567c200dd359ce7e769d2ef1307e686b 80a431a3142374cbdea84f69f0d4ad233e587dcd 8135c8e0aaa037fed06cef529024bb542d811778 +c926a2e3e8d625f956ca998dbab8511a5fa6faab fdc5596b567c200dd359ce7e769d2ef1307e686b +336f2fa350424f15c77ae484a6dabdce57efe3cd c926a2e3e8d625f956ca998dbab8511a5fa6faab +cf0ab2818c32d100fb24fcbfbee83095f06db3ff 336f2fa350424f15c77ae484a6dabdce57efe3cd +fc617462edffa53ba739f285d34e2573e5eadfbf cf0ab2818c32d100fb24fcbfbee83095f06db3ff +3dbc754b35c1ccbed0bbceff0d6f5b9f95f86ad0 fdc5596b567c200dd359ce7e769d2ef1307e686b fc617462edffa53ba739f285d34e2573e5eadfbf +6572f709f59c9d8d14f21fe6208a3252ced62f43 3dbc754b35c1ccbed0bbceff0d6f5b9f95f86ad0 +71af08c8e2cb32a7c9020429ad78cc6492cde74c 3dbc754b35c1ccbed0bbceff0d6f5b9f95f86ad0 6572f709f59c9d8d14f21fe6208a3252ced62f43 +0a99fe8604db22b1d6cd04a18c0b8277e5f9fd06 3dbc754b35c1ccbed0bbceff0d6f5b9f95f86ad0 +26fb14f0aab06f34f4d87724860379a39681435c 0a99fe8604db22b1d6cd04a18c0b8277e5f9fd06 +e68f0d69f70aeb2abd5f6c2cd7ba3b2bfcbbe038 26fb14f0aab06f34f4d87724860379a39681435c +14005e1e1ae15a451003ac6183842f3133648377 e68f0d69f70aeb2abd5f6c2cd7ba3b2bfcbbe038 +3c1339033c7cfeec31b8430832a539f19ca32fde 71af08c8e2cb32a7c9020429ad78cc6492cde74c 14005e1e1ae15a451003ac6183842f3133648377 +2110647e584e4d03cb3ac8955366f0889d813cdd 3c1339033c7cfeec31b8430832a539f19ca32fde +d8425be2877c16e9636aff9c8a06a718dccd77ca 2110647e584e4d03cb3ac8955366f0889d813cdd +96251aac3549ce37fe784db1f16b20d8009ed47c 3c1339033c7cfeec31b8430832a539f19ca32fde d8425be2877c16e9636aff9c8a06a718dccd77ca +91d66d0d88b37e12d66aabf631d1d115f5759a44 96251aac3549ce37fe784db1f16b20d8009ed47c +d2eb3daece597fcd8a06b05de693d0ae9e4bc9ee 96251aac3549ce37fe784db1f16b20d8009ed47c 91d66d0d88b37e12d66aabf631d1d115f5759a44 +2854c6e1676d9e6f3cf114a19ddc149739ede6a2 96251aac3549ce37fe784db1f16b20d8009ed47c +9318e9c7c8d80e05d1aaa703f123b1f074da1b2f d2eb3daece597fcd8a06b05de693d0ae9e4bc9ee 2854c6e1676d9e6f3cf114a19ddc149739ede6a2 +ab15948e0bf81b76495d24b50b9164aa7c3fd87b 9318e9c7c8d80e05d1aaa703f123b1f074da1b2f +14cd4f0a4c8d568f022a3f72e13b8557f15e3273 ab15948e0bf81b76495d24b50b9164aa7c3fd87b +d656c9259dc4c92c8cbcb2fe52af188fcb9d66a0 14cd4f0a4c8d568f022a3f72e13b8557f15e3273 +7ed2b33d914b933a332f348f8cdb4b5e180f1983 d656c9259dc4c92c8cbcb2fe52af188fcb9d66a0 +fe4afbb5133bea26fa6bb75c80d8822d55e79abd 7ed2b33d914b933a332f348f8cdb4b5e180f1983 +9b577128081f76427db504728091bd8cf352da7a fe4afbb5133bea26fa6bb75c80d8822d55e79abd +80c20838e1e993c72ce343978d96790b7c4b9d99 9b577128081f76427db504728091bd8cf352da7a +29b99013ffb978eb9b18b187adb44071b7fed8aa 80c20838e1e993c72ce343978d96790b7c4b9d99 +ce1531c75017385833b6f291be7c046f3e3792fc 29b99013ffb978eb9b18b187adb44071b7fed8aa +09df8322016bf8607b97de3251b1e325c7d5837f ce1531c75017385833b6f291be7c046f3e3792fc +7034979045b6db9a67674fcbde5afd928788d98a 09df8322016bf8607b97de3251b1e325c7d5837f +114e97d56090c10f1ee40e507d1fba600fea62c9 7034979045b6db9a67674fcbde5afd928788d98a +8d674c53d5156e16ae8990c52c3d86fffe979e19 114e97d56090c10f1ee40e507d1fba600fea62c9 +0dd7d41ef970210580a8857822757e40c7b5fc2c 8d674c53d5156e16ae8990c52c3d86fffe979e19 +e63e968ec1f0ded955716851df1b1142697db046 0dd7d41ef970210580a8857822757e40c7b5fc2c +2de14c17598c3cd2a3e3150745e5f2fa9be6e965 e63e968ec1f0ded955716851df1b1142697db046 +dbf734d8309e6303470b075dd6f84a80a259b7f6 2de14c17598c3cd2a3e3150745e5f2fa9be6e965 +9a430134a7dd49f9643bbee82119ddeb77c85558 dbf734d8309e6303470b075dd6f84a80a259b7f6 +d920000c65460f8901efd15d9dd00803b8f0f3be 9a430134a7dd49f9643bbee82119ddeb77c85558 +267564a707f21170cc4832c0eecf3826ebc4f037 d920000c65460f8901efd15d9dd00803b8f0f3be +00d2144c65cf54b9d20dafac30473d85f4d1d4e4 9318e9c7c8d80e05d1aaa703f123b1f074da1b2f 267564a707f21170cc4832c0eecf3826ebc4f037 +0508b9a04b5a38416830930f90d08e39a39f44e5 00d2144c65cf54b9d20dafac30473d85f4d1d4e4 +879961f6a013885ccf3f63906e46895c0b5bcb72 00d2144c65cf54b9d20dafac30473d85f4d1d4e4 0508b9a04b5a38416830930f90d08e39a39f44e5 +e64722c0f09ad317e8f239631d421bcde9fa80ad 879961f6a013885ccf3f63906e46895c0b5bcb72 +4edc08f5c0ac0d6ed212ed7fe5eeb9bf5fb61be4 879961f6a013885ccf3f63906e46895c0b5bcb72 e64722c0f09ad317e8f239631d421bcde9fa80ad +2c695b96152d33f29ea6c0f03e9b894ab998b4e5 879961f6a013885ccf3f63906e46895c0b5bcb72 +a13e4d496aefff6d85c5229bad31f02513755ad3 2c695b96152d33f29ea6c0f03e9b894ab998b4e5 +c09ffe8e3e1a67eff2e5784c8dca0b5da3200171 4edc08f5c0ac0d6ed212ed7fe5eeb9bf5fb61be4 a13e4d496aefff6d85c5229bad31f02513755ad3 +da28413ecbd0071987fc624f6b24ad01ba36379b c09ffe8e3e1a67eff2e5784c8dca0b5da3200171 +10f7ca09ad05240ad0cfc6e27e1453d7f4fd06a9 c09ffe8e3e1a67eff2e5784c8dca0b5da3200171 da28413ecbd0071987fc624f6b24ad01ba36379b +b54af32465c6062d8362e8b8aaf454c57cc2f9c3 c09ffe8e3e1a67eff2e5784c8dca0b5da3200171 +df2f4d2ded9c614f24a170461c71464907a11f3d b54af32465c6062d8362e8b8aaf454c57cc2f9c3 +ce67dd470b30be21387b7a103da9f46b82abbfd3 df2f4d2ded9c614f24a170461c71464907a11f3d +fce89a30de8923f1ebffa9acf88c038352f89e6b ce67dd470b30be21387b7a103da9f46b82abbfd3 +09ef0c21e8cbe3aed6ed5cbfeca79675aa7ec066 10f7ca09ad05240ad0cfc6e27e1453d7f4fd06a9 fce89a30de8923f1ebffa9acf88c038352f89e6b +0d80423bbe29d807a9d85c0199a3a743f1fb6130 09ef0c21e8cbe3aed6ed5cbfeca79675aa7ec066 +c90dc001888b4f4ede6b2d182c413652ebd8ce28 09ef0c21e8cbe3aed6ed5cbfeca79675aa7ec066 0d80423bbe29d807a9d85c0199a3a743f1fb6130 +a7d19425dcb6d23ed34f99169d5d576378bf7992 c90dc001888b4f4ede6b2d182c413652ebd8ce28 +57c0973a0ceebbc7251b2102a4c2849e2d4aa4e5 c90dc001888b4f4ede6b2d182c413652ebd8ce28 a7d19425dcb6d23ed34f99169d5d576378bf7992 +acf355fbf8facae3ac233188173ecc94fbc27536 c90dc001888b4f4ede6b2d182c413652ebd8ce28 +dcc2383feaee643a5b7cb1ecf35a007bc79b674a 57c0973a0ceebbc7251b2102a4c2849e2d4aa4e5 acf355fbf8facae3ac233188173ecc94fbc27536 +593b4202dcf21b20ae4be2853e892dceae4eb71b dcc2383feaee643a5b7cb1ecf35a007bc79b674a +e01a5d794fd6cdf83a04ab257133f33d9d09de55 dcc2383feaee643a5b7cb1ecf35a007bc79b674a 593b4202dcf21b20ae4be2853e892dceae4eb71b +df1734e02e4a56c3650fed27c6665c249f9e31e3 e01a5d794fd6cdf83a04ab257133f33d9d09de55 +515289571b1a018e47080b1f0bf365742fd5b4ef e01a5d794fd6cdf83a04ab257133f33d9d09de55 df1734e02e4a56c3650fed27c6665c249f9e31e3 +9f82b6ff55d06d581aee99e65508c56d0c4d0e60 515289571b1a018e47080b1f0bf365742fd5b4ef +1fbaf35f5dc96eb7d2af2fd8488956cb156916aa 515289571b1a018e47080b1f0bf365742fd5b4ef 9f82b6ff55d06d581aee99e65508c56d0c4d0e60 +895f2b5dbefabbb94b72b01bebd2862afdfc0fde 515289571b1a018e47080b1f0bf365742fd5b4ef +ee240e0b4356d1b77e4ca9526d682341984ee0c8 1fbaf35f5dc96eb7d2af2fd8488956cb156916aa 895f2b5dbefabbb94b72b01bebd2862afdfc0fde +e862ff50dbae812039619ae7946f59684d9758b1 ee240e0b4356d1b77e4ca9526d682341984ee0c8 +a1f3b6c8654dfac3e79eecfc9c14f69bb7860da8 ee240e0b4356d1b77e4ca9526d682341984ee0c8 e862ff50dbae812039619ae7946f59684d9758b1 +62ca1661b66d0abe336c04f25d7fa6e55c94f941 515289571b1a018e47080b1f0bf365742fd5b4ef +c2bddfca8196c81ca6784503f17fc654aefa20ad 62ca1661b66d0abe336c04f25d7fa6e55c94f941 +928cc490a9374c6e0e37d94d49b73dcbe3c97389 c2bddfca8196c81ca6784503f17fc654aefa20ad +143ecbe14db7c2e82545500473afae3b8170d2d7 928cc490a9374c6e0e37d94d49b73dcbe3c97389 +4e2acb3ba20826e9734edb9d41bb0aa2c9bb5f70 a1f3b6c8654dfac3e79eecfc9c14f69bb7860da8 143ecbe14db7c2e82545500473afae3b8170d2d7 +f2cc0780897b772879c83b7346c1f4138c01d656 515289571b1a018e47080b1f0bf365742fd5b4ef +47fbc04e6fd496dcb60c655fc4fcf9bf75218a8b 4e2acb3ba20826e9734edb9d41bb0aa2c9bb5f70 f2cc0780897b772879c83b7346c1f4138c01d656 +18fa261e3245a9e38c677c9fc20d43f2be2a12bd 4e2acb3ba20826e9734edb9d41bb0aa2c9bb5f70 +091790e7ac6839cdbfc18d84d8a6d7c04e56c4ea 18fa261e3245a9e38c677c9fc20d43f2be2a12bd +5a7c0d041c5e634bf71b883760240f273ce8fa04 47fbc04e6fd496dcb60c655fc4fcf9bf75218a8b 091790e7ac6839cdbfc18d84d8a6d7c04e56c4ea +a01dea33998e7b873685b675393a3953d09d0b78 5a7c0d041c5e634bf71b883760240f273ce8fa04 +159e653e364c71923ab865baedb9443c2f2280d2 a01dea33998e7b873685b675393a3953d09d0b78 +435cd0ecd6f54dedd4272d13e209e9dacc48f15d 159e653e364c71923ab865baedb9443c2f2280d2 +2d6aa8cf96d0e22d6b196f5276bd297e7ec05fb4 5a7c0d041c5e634bf71b883760240f273ce8fa04 435cd0ecd6f54dedd4272d13e209e9dacc48f15d +0f7371342e2ff43cf4a1bbcb2708da081fb6d982 2d6aa8cf96d0e22d6b196f5276bd297e7ec05fb4 +d3f34db3d9514592edd1e38e5f47794beac3dfde 2d6aa8cf96d0e22d6b196f5276bd297e7ec05fb4 0f7371342e2ff43cf4a1bbcb2708da081fb6d982 +2c51921b37731bb89521d9e3858bc310d4aa1d81 d3f34db3d9514592edd1e38e5f47794beac3dfde +7251ff662a3bfe35cbe61b10d46d08bd5037998d d3f34db3d9514592edd1e38e5f47794beac3dfde 2c51921b37731bb89521d9e3858bc310d4aa1d81 +8e3233a791262db7ea31154e3748b6af9abbd5de d3f34db3d9514592edd1e38e5f47794beac3dfde +2bb8c9db233ee7d02cac59b2f4a9ce69669f603a 7251ff662a3bfe35cbe61b10d46d08bd5037998d 8e3233a791262db7ea31154e3748b6af9abbd5de +b64bd3b1a0255973f9776ab6524b4905b7f1eb1b 2bb8c9db233ee7d02cac59b2f4a9ce69669f603a +44666213a7007b992a55119e02ad29412c7afda8 b64bd3b1a0255973f9776ab6524b4905b7f1eb1b +716eb6096bc7927fe26be823378ebec8922c9859 44666213a7007b992a55119e02ad29412c7afda8 +f196b2f53bf757b349485e91ec92110ba6c3815d 716eb6096bc7927fe26be823378ebec8922c9859 +7aa7344d1f3cadb157e4bdc8a9f9a7828f462442 f196b2f53bf757b349485e91ec92110ba6c3815d +85d3bdfaeb9ec08e05eb45a3b8fe7e4ac4f713a8 7aa7344d1f3cadb157e4bdc8a9f9a7828f462442 +ef5301c01c52cf620add3625b08285576169e635 85d3bdfaeb9ec08e05eb45a3b8fe7e4ac4f713a8 +f62d1c06d3dad4c333e55ac179af4af1c987c8d3 ef5301c01c52cf620add3625b08285576169e635 +418cd7b5f5883efde13d1ef145cf0db187f06277 f62d1c06d3dad4c333e55ac179af4af1c987c8d3 +c501fcdf32bc183361c451523bae1f9574ba7049 418cd7b5f5883efde13d1ef145cf0db187f06277 +e5c395f906e84d669b33b10e9fcc97cfa6917a46 c501fcdf32bc183361c451523bae1f9574ba7049 +907463dd61e4ce58e450863e2e0d9f86254f8b46 2bb8c9db233ee7d02cac59b2f4a9ce69669f603a e5c395f906e84d669b33b10e9fcc97cfa6917a46 +76b2d51db4a8dedc008e80101cb9ec4defa6c5ad 907463dd61e4ce58e450863e2e0d9f86254f8b46 +cf8f02a278f1dcc1ac768f0c3eb0b4116dbd1daa 907463dd61e4ce58e450863e2e0d9f86254f8b46 76b2d51db4a8dedc008e80101cb9ec4defa6c5ad +3bc68b4b959d02f47a739a5058090ec4a8d26eac cf8f02a278f1dcc1ac768f0c3eb0b4116dbd1daa +b3f1c4cf9caa2a19784d2e24795beca533e92784 3bc68b4b959d02f47a739a5058090ec4a8d26eac +6cfff1e4ddbf98b41f1f2a1f64915a64e58c3506 b3f1c4cf9caa2a19784d2e24795beca533e92784 +f932fe9c6f727597cba6bd5e7402fd90cf0f3caf 6cfff1e4ddbf98b41f1f2a1f64915a64e58c3506 +25d364412a4916c5c799b8e6d8c9abfe5bb63bed f932fe9c6f727597cba6bd5e7402fd90cf0f3caf +a24df9018c6e1764044dafc8cf2ea7cb1f823aaa 25d364412a4916c5c799b8e6d8c9abfe5bb63bed +81dd1a8a369fd30089a5d871841dfc16ebab594a a24df9018c6e1764044dafc8cf2ea7cb1f823aaa +7b0b60d235bd74b4410bd85d459357734587560f 81dd1a8a369fd30089a5d871841dfc16ebab594a +f1485b2924853d9f6494d1d1ca4bb5bdd898c23c cf8f02a278f1dcc1ac768f0c3eb0b4116dbd1daa 7b0b60d235bd74b4410bd85d459357734587560f +8094a495969905a89f846cec4be87044d1c7794d f1485b2924853d9f6494d1d1ca4bb5bdd898c23c +c876c2a90fd4e41ac51387e88f3cc0b3ce561c7c f1485b2924853d9f6494d1d1ca4bb5bdd898c23c 8094a495969905a89f846cec4be87044d1c7794d +13be0eca33b9f8efd8ea88de7b0c19a655eda0f9 c876c2a90fd4e41ac51387e88f3cc0b3ce561c7c +27cd8c0492507c9a9e9e280463433d1a5d274eb7 c876c2a90fd4e41ac51387e88f3cc0b3ce561c7c 13be0eca33b9f8efd8ea88de7b0c19a655eda0f9 +0a39543fef4a880adc2e5b3bb068cf82213b47d3 c876c2a90fd4e41ac51387e88f3cc0b3ce561c7c +395a535f54af1ed71c62175c6f3aa24ad7c3b06d 0a39543fef4a880adc2e5b3bb068cf82213b47d3 +b1ae49b2497799bda6ccb8100682a9559066d469 27cd8c0492507c9a9e9e280463433d1a5d274eb7 395a535f54af1ed71c62175c6f3aa24ad7c3b06d +d95bc78077e0e51b1d0ec5060e24024589cec428 c876c2a90fd4e41ac51387e88f3cc0b3ce561c7c +b840b9f2f12fd5d196679a952e0069db32340a69 d95bc78077e0e51b1d0ec5060e24024589cec428 +7e930f5b34aa0b9b909dce881f8bbe5a98a9a18e b1ae49b2497799bda6ccb8100682a9559066d469 b840b9f2f12fd5d196679a952e0069db32340a69 +e6c3363f47a7761c41f2bffa3712b67518344e54 7e930f5b34aa0b9b909dce881f8bbe5a98a9a18e +05766bbf38e1ba34ccc1957f4f4605324acc979a e6c3363f47a7761c41f2bffa3712b67518344e54 +04e5f029090c046dab273a7c012191fe3184124d 05766bbf38e1ba34ccc1957f4f4605324acc979a +6507847c2e75b287bb37e56403ebaa4b3dbf5834 7e930f5b34aa0b9b909dce881f8bbe5a98a9a18e 04e5f029090c046dab273a7c012191fe3184124d +719204369934084ec7dc1bd4eb3f33056996ae60 6507847c2e75b287bb37e56403ebaa4b3dbf5834 +2741d37db734bd9387fd3642d4b7b3a850a840dd 6507847c2e75b287bb37e56403ebaa4b3dbf5834 719204369934084ec7dc1bd4eb3f33056996ae60 +fb5a79854ce0c74f306d4e2091c733b9057b9cd0 2741d37db734bd9387fd3642d4b7b3a850a840dd +d7f10e07da062b3860fd01d0edf0d4b35eb7bad6 fb5a79854ce0c74f306d4e2091c733b9057b9cd0 +95bc551ececc127eda318beebb0b046cb665d398 2741d37db734bd9387fd3642d4b7b3a850a840dd d7f10e07da062b3860fd01d0edf0d4b35eb7bad6 +7d252eb9ae1807dd9e164216c866e973ecb327dd 95bc551ececc127eda318beebb0b046cb665d398 +661a4a453dd8154ce996f02edd27dc5fc0fd18ee 95bc551ececc127eda318beebb0b046cb665d398 7d252eb9ae1807dd9e164216c866e973ecb327dd +b50761ce2a41a5362428d8b0aa9a055da9288b1e 95bc551ececc127eda318beebb0b046cb665d398 +111f2faefe93b4679313d95f1c545bcf33cb38b3 b50761ce2a41a5362428d8b0aa9a055da9288b1e +78ce23d560214b42af54933be6172744c0b46967 111f2faefe93b4679313d95f1c545bcf33cb38b3 +3d5e2bb689d650d0c1ff66e89951ec65a196e0e3 78ce23d560214b42af54933be6172744c0b46967 +92e877657d5327ddb337c9a177be02d31435d94d 3d5e2bb689d650d0c1ff66e89951ec65a196e0e3 +95908c335a9d19d871dbde930501f62068c0009b 92e877657d5327ddb337c9a177be02d31435d94d +ca667e4bf53d3c4943f4467a36bf8503e458c53f 661a4a453dd8154ce996f02edd27dc5fc0fd18ee 95908c335a9d19d871dbde930501f62068c0009b +1d500c7c77af059e92599abc9703d3b78f4686a7 ca667e4bf53d3c4943f4467a36bf8503e458c53f +299365c12dfecf817b89c77baf34b6543f6024d8 ca667e4bf53d3c4943f4467a36bf8503e458c53f 1d500c7c77af059e92599abc9703d3b78f4686a7 +3680c2910b6fb37af52353493de718f41efb8428 ca667e4bf53d3c4943f4467a36bf8503e458c53f +33057ff3e93da010206e39f71ac95da434e93ff5 299365c12dfecf817b89c77baf34b6543f6024d8 3680c2910b6fb37af52353493de718f41efb8428 +864999337a47157e63c2776a6d6b290a85b8cb9d 33057ff3e93da010206e39f71ac95da434e93ff5 +0ebb9de5d93fc9167e74d0e1b8399ebd87f5be1b 864999337a47157e63c2776a6d6b290a85b8cb9d +d6aa4e76727e1e1b0113e834f0613df2f96edbf7 33057ff3e93da010206e39f71ac95da434e93ff5 0ebb9de5d93fc9167e74d0e1b8399ebd87f5be1b +d28e51cbad08203ac94b12e2bea0618a2ea7e9a0 2741d37db734bd9387fd3642d4b7b3a850a840dd +9b2fef36c29042dd43cbc9bec5352cb62ef84674 d6aa4e76727e1e1b0113e834f0613df2f96edbf7 d28e51cbad08203ac94b12e2bea0618a2ea7e9a0 +eb612d2c60c970946ab2316692491ac16873fa62 9b2fef36c29042dd43cbc9bec5352cb62ef84674 +67109b9d96783bd06baeaddd18c617947de7f41f 9b2fef36c29042dd43cbc9bec5352cb62ef84674 eb612d2c60c970946ab2316692491ac16873fa62 +0343d8de3de187f494d2b9efd0c2ce10efa80b92 67109b9d96783bd06baeaddd18c617947de7f41f +d53312a3fc2ec137e9f7c17d90e6d5c313304f3e 67109b9d96783bd06baeaddd18c617947de7f41f 0343d8de3de187f494d2b9efd0c2ce10efa80b92 +77b068799df4223e55d70021648709a4d28ab18d d53312a3fc2ec137e9f7c17d90e6d5c313304f3e +d05313bde79eeb0eff8cb2b36e9e9ccc98584c09 d53312a3fc2ec137e9f7c17d90e6d5c313304f3e 77b068799df4223e55d70021648709a4d28ab18d +f33186770590ee9f439248c001ae33f1e565d457 d05313bde79eeb0eff8cb2b36e9e9ccc98584c09 +7d3bee8636a539c4511a2c6787f1296ab05d1065 d05313bde79eeb0eff8cb2b36e9e9ccc98584c09 f33186770590ee9f439248c001ae33f1e565d457 +dce2303eb05d307787fd44a81c4814f714d67481 7d3bee8636a539c4511a2c6787f1296ab05d1065 +bd587d2a30fe83380e03a3edb919688306b60826 7d3bee8636a539c4511a2c6787f1296ab05d1065 dce2303eb05d307787fd44a81c4814f714d67481 +a6a97d6c8f5c262936f49640febc1d4f4efc645c bd587d2a30fe83380e03a3edb919688306b60826 +cd00c096f92f41b63bedc548b8e9b147cc5c8630 a6a97d6c8f5c262936f49640febc1d4f4efc645c +152bb2757da5b19ee47e75c6125ca426b528c183 cd00c096f92f41b63bedc548b8e9b147cc5c8630 +c1db9f7dd9b8dd08d07216ddbbed8e22954c7d30 152bb2757da5b19ee47e75c6125ca426b528c183 +7c3fd65d44c6971d78338277f08f9b8fc0da0a3c c1db9f7dd9b8dd08d07216ddbbed8e22954c7d30 +341b7d45a28156a6892846d443292988156752e7 7c3fd65d44c6971d78338277f08f9b8fc0da0a3c +7e92e5baa7892940825d9749296237e08f64078b 341b7d45a28156a6892846d443292988156752e7 +0e4cc00dde4bd48d0d0e39752d807e4954cc7ab6 7e92e5baa7892940825d9749296237e08f64078b +0be8643f31682c50f2cd5898945840848eb6e960 0e4cc00dde4bd48d0d0e39752d807e4954cc7ab6 +ec712083ddf58ad819dc39396a6d8ae0c6aa1241 bd587d2a30fe83380e03a3edb919688306b60826 0be8643f31682c50f2cd5898945840848eb6e960 +602a33e3806759fd44fc50f7a14b267422ff2266 67109b9d96783bd06baeaddd18c617947de7f41f +ab172a1f34ec6463015b2ebed3609ab60ec397b9 ec712083ddf58ad819dc39396a6d8ae0c6aa1241 602a33e3806759fd44fc50f7a14b267422ff2266 +9b2a33f3c397390974a90b4f018549dcc790ff2c ec712083ddf58ad819dc39396a6d8ae0c6aa1241 +84adbc03a2fcbee0e4b7aaec0b44d20b4e9b853c ab172a1f34ec6463015b2ebed3609ab60ec397b9 9b2a33f3c397390974a90b4f018549dcc790ff2c +4e74a2a8a4dbad2590efefa3398d626c06c0067e 84adbc03a2fcbee0e4b7aaec0b44d20b4e9b853c +5e667391af72830fcf90b41b6b2768d98f1b5b0e 84adbc03a2fcbee0e4b7aaec0b44d20b4e9b853c 4e74a2a8a4dbad2590efefa3398d626c06c0067e +87668e00cb8a7b18508b1754e8100a7334899364 5e667391af72830fcf90b41b6b2768d98f1b5b0e +ab7639e6f5f6c8e4ce1a5836341764bd6a401e2a 5e667391af72830fcf90b41b6b2768d98f1b5b0e 87668e00cb8a7b18508b1754e8100a7334899364 +b79a49d42986eae8ee572b2278330ed82a64e527 ab7639e6f5f6c8e4ce1a5836341764bd6a401e2a +788b2809a050e5efcd96823f0aabbdae9d33d1de ab7639e6f5f6c8e4ce1a5836341764bd6a401e2a b79a49d42986eae8ee572b2278330ed82a64e527 +863e2e09c136ed2b66edda30623cc4bbcf6eb6d7 ab7639e6f5f6c8e4ce1a5836341764bd6a401e2a +e5dd9e159815bb0dbdf196cda209e8090eba0d7d 788b2809a050e5efcd96823f0aabbdae9d33d1de 863e2e09c136ed2b66edda30623cc4bbcf6eb6d7 +27a100b3810936b8e7d83311d0e3b0dfaba8ff29 5e667391af72830fcf90b41b6b2768d98f1b5b0e +f4acdbc080eda00e298aabea915dbc6b56b625fd 27a100b3810936b8e7d83311d0e3b0dfaba8ff29 +9146ebc449cfa07e020335d64919c38b5e895cff f4acdbc080eda00e298aabea915dbc6b56b625fd +4d039bec8368ab7a8f50e18e8ebba74e0c682f3a 9146ebc449cfa07e020335d64919c38b5e895cff +340987b5824178fbcd8eeed9a5a506a5e9c2e368 4d039bec8368ab7a8f50e18e8ebba74e0c682f3a +d6e4ad97c508ef2af991431e2a0fa5b6bd8792c0 340987b5824178fbcd8eeed9a5a506a5e9c2e368 +9967b8ab07e7e3409b4f9257754bc22e84e7ebb1 d6e4ad97c508ef2af991431e2a0fa5b6bd8792c0 +8fd51669b7e0eb2d4927c8c408b350ca9a6ab4b2 9967b8ab07e7e3409b4f9257754bc22e84e7ebb1 +ba1e048900efdeb656dba3ef31a2745a058c4692 8fd51669b7e0eb2d4927c8c408b350ca9a6ab4b2 +4a9e0b984877fa3ddc095f7bb8a8ef6326f09ec2 ba1e048900efdeb656dba3ef31a2745a058c4692 +e62df9482cbde20376427809569fb88835dce7d0 4a9e0b984877fa3ddc095f7bb8a8ef6326f09ec2 +e4eb7650d3b02da67f6a7865422bad9c32a9e5f8 e62df9482cbde20376427809569fb88835dce7d0 +c4bc765806e9d45668778939bb7e4ba1e13b66bc e4eb7650d3b02da67f6a7865422bad9c32a9e5f8 +8ebf293b1f09caac7d54afa2f4ded3e3572977f7 c4bc765806e9d45668778939bb7e4ba1e13b66bc +7018ce65f18df5aadeb32cff56f54743e826f845 8ebf293b1f09caac7d54afa2f4ded3e3572977f7 +e311f2f65968fb302545319197a8573b298bd598 7018ce65f18df5aadeb32cff56f54743e826f845 +0b4c4887bfeed88068cf8efed903dcfe851386fa e311f2f65968fb302545319197a8573b298bd598 +dd7a587ace3872cc78fdbc944ecfff9d9ded445a 0b4c4887bfeed88068cf8efed903dcfe851386fa +8182615defad527e3f1ad9888f65e40572eca7d4 dd7a587ace3872cc78fdbc944ecfff9d9ded445a +b0fd1fa646dfdd3134551bb70859702f09843b32 8182615defad527e3f1ad9888f65e40572eca7d4 +5037bdb93b51cc5618861bc460e2ed1ed1a01b2b b0fd1fa646dfdd3134551bb70859702f09843b32 +af9b13613d1f828421b51bd3ff715c9cb6a1279f 5037bdb93b51cc5618861bc460e2ed1ed1a01b2b +71cf21ea34fe15452b5c08c88b853c06215bc473 af9b13613d1f828421b51bd3ff715c9cb6a1279f +530bc9d6b705dfa142e347d34538a70d4e8fb82e e5dd9e159815bb0dbdf196cda209e8090eba0d7d 71cf21ea34fe15452b5c08c88b853c06215bc473 +5e10220036a1ca00f7c8d38529d87dc258e3ac8c 530bc9d6b705dfa142e347d34538a70d4e8fb82e +7f94f25717f040cc3aae45f67b2b93ee42fe1049 530bc9d6b705dfa142e347d34538a70d4e8fb82e 5e10220036a1ca00f7c8d38529d87dc258e3ac8c +819cb3809b3227426180872c49406f94dac5aa4e 530bc9d6b705dfa142e347d34538a70d4e8fb82e +00bde28a3a4f141cad491af027c08fa5a6b10a8a 819cb3809b3227426180872c49406f94dac5aa4e +99348e475c65282dac863220ea70bc798a2f8f16 7f94f25717f040cc3aae45f67b2b93ee42fe1049 00bde28a3a4f141cad491af027c08fa5a6b10a8a +594f5cbfee1cb785baa9a62575336b1fb19b21f8 7d3bee8636a539c4511a2c6787f1296ab05d1065 +45641a9d9c108e8c7e81496e969d7903f943d53d 594f5cbfee1cb785baa9a62575336b1fb19b21f8 +a1c497abe68ec472050bd78e5046e2c923969998 45641a9d9c108e8c7e81496e969d7903f943d53d +db419fbfcca99ee4bb05adb68060d9a32a4cdb4b a1c497abe68ec472050bd78e5046e2c923969998 +112b5cbb1d4a9ddc0c0f3a35958b8172353035a5 db419fbfcca99ee4bb05adb68060d9a32a4cdb4b +c3c6c9ff9b18c25eacf378d723805d724aeac9bd 112b5cbb1d4a9ddc0c0f3a35958b8172353035a5 +8cfbe4e1994949fbe49e4aa5254acef231658318 c3c6c9ff9b18c25eacf378d723805d724aeac9bd +3ab38ff448cd85bf23a5a0727de3ac51083ce3fb 8cfbe4e1994949fbe49e4aa5254acef231658318 +d5f327b78b9b8430bf888381f7ef025a4a43fe97 3ab38ff448cd85bf23a5a0727de3ac51083ce3fb +a6a3a492f21f7ba050b3090fe8a7cd6f31b92015 d5f327b78b9b8430bf888381f7ef025a4a43fe97 +108f53cd8284d48b929240dfa59b474e244abf78 a6a3a492f21f7ba050b3090fe8a7cd6f31b92015 +75e8fbc7857667080b2f35b1945b528d1bf18632 108f53cd8284d48b929240dfa59b474e244abf78 +74e551121b0c5c26ebd2a9b52e2b7a982b65e84a 75e8fbc7857667080b2f35b1945b528d1bf18632 +493bc3f2fbed5395e038ef548c9d73bae70ded05 74e551121b0c5c26ebd2a9b52e2b7a982b65e84a +b63fc69fd263f72bb50da684d7256e44ad377c59 493bc3f2fbed5395e038ef548c9d73bae70ded05 +46d28ea928cad6662ec5008d092da45da307b543 b63fc69fd263f72bb50da684d7256e44ad377c59 +bd6311d8a972b8ca39ea33582787d218ea50d6e7 46d28ea928cad6662ec5008d092da45da307b543 5e667391af72830fcf90b41b6b2768d98f1b5b0e +d7d869c0629b8b2be74e214633f3f1ebc2898ec7 bd6311d8a972b8ca39ea33582787d218ea50d6e7 +8de53b6a0ca8ceb962c1a3e67c1664f54c2d606a d7d869c0629b8b2be74e214633f3f1ebc2898ec7 +66ea5adcc74e7472713474edce3baa7b4f071406 8de53b6a0ca8ceb962c1a3e67c1664f54c2d606a e5dd9e159815bb0dbdf196cda209e8090eba0d7d +d1ad0962c192dc7bd0a03f83dcb918e92b6ec3e3 46d28ea928cad6662ec5008d092da45da307b543 +3e054efd4071634ac5bf79a88388e8906c58ea4b d1ad0962c192dc7bd0a03f83dcb918e92b6ec3e3 +090317e93e5312becba767685e137d9b7b2fce91 66ea5adcc74e7472713474edce3baa7b4f071406 3e054efd4071634ac5bf79a88388e8906c58ea4b +982bcecc3cddfb2d7fceec8412f756f5807b1f55 090317e93e5312becba767685e137d9b7b2fce91 +c5a598c997540acc9704de3a0c31611e7c96f5a5 982bcecc3cddfb2d7fceec8412f756f5807b1f55 +c41e88e54a9df37899c88639a1156ced895cb6fa c5a598c997540acc9704de3a0c31611e7c96f5a5 +aef9d08b869c8817f5e153c5b16ef9db7ebdf860 c41e88e54a9df37899c88639a1156ced895cb6fa +948439eb13ff50c183eba5ec4a4058b6c2d15bfa aef9d08b869c8817f5e153c5b16ef9db7ebdf860 +6197b95a7c2d96bfc36cdae66c02e8f6b1ca5258 948439eb13ff50c183eba5ec4a4058b6c2d15bfa +a118af41625e33cb366abb5936e720cc96f3d0b0 6197b95a7c2d96bfc36cdae66c02e8f6b1ca5258 diff --git a/.gitignore b/.gitignore index 40b5914..8a23a36 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ build/ *.out *.silo +run/ +.vscode/ diff --git a/=0.11.1 b/=0.11.1 new file mode 100644 index 0000000..e69de29 diff --git a/=1.0.0 b/=1.0.0 new file mode 100644 index 0000000..e69de29 diff --git a/examples/mechanics/CMakeLists.txt b/examples/mechanics/CMakeLists.txt index a10b05f..3e698e3 100644 --- a/examples/mechanics/CMakeLists.txt +++ b/examples/mechanics/CMakeLists.txt @@ -10,4 +10,8 @@ target_link_libraries(CrackBranching LINK_PUBLIC CabanaPD) add_executable(FragmentingCylinder fragmenting_cylinder.cpp) target_link_libraries(FragmentingCylinder LINK_PUBLIC CabanaPD) -install(TARGETS ElasticWave KalthoffWinkler CrackBranching FragmentingCylinder DESTINATION ${CMAKE_INSTALL_BINDIR}) +add_executable(CentralCrack central_crack.cpp) +target_link_libraries(CentralCrack LINK_PUBLIC CabanaPD) + + +install(TARGETS ElasticWave KalthoffWinkler CrackBranching FragmentingCylinder CentralCrack DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/examples/mechanics/central_crack.cpp b/examples/mechanics/central_crack.cpp new file mode 100644 index 0000000..fc97db2 --- /dev/null +++ b/examples/mechanics/central_crack.cpp @@ -0,0 +1,175 @@ +/**************************************************************************** + * Copyright (c) 2022 by Oak Ridge National Laboratory * + * All rights reserved. * + * * + * This file is part of CabanaPD. CabanaPD is distributed under a * + * BSD 3-clause license. For the licensing terms see the LICENSE file in * + * the top-level directory. * + * * + * SPDX-License-Identifier: BSD-3-Clause * + ****************************************************************************/ + +#include +#include + +#include "mpi.h" + +#include + +#include + +// Simulate a square plate with a central crack under tension. +void centralCrackExample( const std::string filename ) +{ + // ==================================================== + // Use default Kokkos spaces + // ==================================================== + using exec_space = Kokkos::DefaultExecutionSpace; + using memory_space = typename exec_space::memory_space; + + // ==================================================== + // Read inputs + // ==================================================== + CabanaPD::Inputs inputs( filename ); + + // ==================================================== + // Material parameters + // ==================================================== + double rho0 = inputs["density"]; + double E = inputs["elastic_modulus"]; + double nu = 0.25; // Use bond-based model + double K = E / ( 3 * ( 1 - 2 * nu ) ); + double G0 = inputs["fracture_energy"]; + double delta = inputs["horizon"]; + delta += 1e-10; + + // ==================================================== + // Discretization + // ==================================================== + // Set halo width based on delta + std::array low_corner = inputs["low_corner"]; + std::array high_corner = inputs["high_corner"]; + + // ==================================================== + // Central Crack + // ==================================================== + double thickness = inputs["system_size"][2]; // Plate thickness + double crack_length = 0.01; // Crack length is 10 mm + + // Assume the plate is symmetric, ranging from -0.025 to +0.025 + double plate_center_x = 0.0; // Center is at 0 for symmetric coordinates + double plate_center_y = 0.0; // Center is at 0 for symmetric coordinates + + // Define the crack start and end points for a horizontal crack + Kokkos::Array crack_start = { + plate_center_x - + ( crack_length / 2.0 ), // Center the crack along the x-axis + plate_center_y, // Center the crack along the y-axis + 0.0 // Assume the crack lies in the z=0 plane + }; + Kokkos::Array crack_end = { + plate_center_x + + ( crack_length / 2.0 ), // Center the crack along the x-axis + plate_center_y, // Center the crack along the y-axis + 0.0 // Assume the crack lies in the z=0 plane + }; + + // Compute the vector defining the crack + Kokkos::Array crack_vector = { crack_end[0] - crack_start[0], + crack_end[1] - crack_start[1], + crack_end[2] - crack_start[2] }; + + // Define the crack using Prenotch + Kokkos::Array, 2> notch_positions = { crack_start, + crack_end }; + CabanaPD::Prenotch<2> prenotch( crack_vector, { 0.0, 0.0, thickness }, + notch_positions ); + + // ==================================================== + // Force model + // ==================================================== + using model_type = CabanaPD::ForceModel; + model_type force_model( delta, K, G0 ); + + // ==================================================== + // Particle generation + // ==================================================== + auto particles = CabanaPD::createParticles( + exec_space{}, inputs, CabanaPD::EnergyStressOutput{} ); + + // ==================================================== + // Boundary conditions planes + // ==================================================== + double dy = particles->dx[1]; + CabanaPD::RegionBoundary plane1( + low_corner[0], high_corner[0], low_corner[1] - dy, low_corner[1] + dy, + low_corner[2], high_corner[2] ); + CabanaPD::RegionBoundary plane2( + low_corner[0], high_corner[0], high_corner[1] - dy, high_corner[1] + dy, + low_corner[2], high_corner[2] ); + std::vector> planes = { + plane1, plane2 }; + + // ==================================================== + // Custom particle initialization + // ==================================================== + auto rho = particles->sliceDensity(); + auto x = particles->sliceReferencePosition(); + auto v = particles->sliceVelocity(); + auto f = particles->sliceForce(); + auto nofail = particles->sliceNoFail(); + + auto init_functor = KOKKOS_LAMBDA( const int pid ) + { + // Density + rho( pid ) = rho0; + // No-fail zone + if ( x( pid, 1 ) <= plane1.low_y + delta + 1e-10 || + x( pid, 1 ) >= plane2.high_y - delta - 1e-10 ) + nofail( pid ) = 1; + }; + particles->updateParticles( exec_space{}, init_functor ); + + // ==================================================== + // Create solver + // ==================================================== + auto cabana_pd = CabanaPD::createSolverFracture( + inputs, particles, force_model ); + + // ==================================================== + // Boundary conditions + // ==================================================== + // Create BC last to ensure ghost particles are included. + double sigma0 = inputs["traction"]; + double b0 = sigma0 / dy; + f = particles->sliceForce(); + x = particles->sliceReferencePosition(); + // Create a symmetric force BC in the y-direction. + auto bc_op = KOKKOS_LAMBDA( const int pid, const double ) + { + auto ypos = x( pid, 1 ); + auto sign = + ( ypos > ( low_corner[1] + high_corner[1] ) / 2.0 ) ? 1.0 : -1.0; + f( pid, 1 ) += b0 * sign; + }; + auto bc = createBoundaryCondition( bc_op, exec_space{}, *particles, planes, + true ); + + // ==================================================== + // Simulation run + // ==================================================== + cabana_pd->init( bc, prenotch ); + cabana_pd->run( bc ); +} + +// Initialize MPI+Kokkos. +int main( int argc, char* argv[] ) +{ + MPI_Init( &argc, &argv ); + Kokkos::initialize( argc, argv ); + + centralCrackExample( argv[1] ); + + Kokkos::finalize(); + MPI_Finalize(); +} diff --git a/examples/mechanics/crack_branching.cpp b/examples/mechanics/crack_branching.cpp index b380472..e8189dc 100644 --- a/examples/mechanics/crack_branching.cpp +++ b/examples/mechanics/crack_branching.cpp @@ -75,7 +75,7 @@ void crackBranchingExample( const std::string filename ) // ==================================================== // Note that individual inputs can be passed instead (see other examples). auto particles = CabanaPD::createParticles( - exec_space{}, inputs ); + exec_space{}, inputs, CabanaPD::EnergyStressOutput{} ); // ==================================================== // Boundary conditions planes diff --git a/examples/mechanics/inputs/central_crack.json b/examples/mechanics/inputs/central_crack.json new file mode 100644 index 0000000..6bbbf4d --- /dev/null +++ b/examples/mechanics/inputs/central_crack.json @@ -0,0 +1,14 @@ +{ + "num_cells": {"value": [424, 424, 3], "original": [848, 848, 17]}, + "system_size": {"value": [0.05, 0.05, 0.001], "unit": "m"}, + "density": {"value": 2440, "unit": "kg/m^3"}, + "elastic_modulus": {"value": 72e+9, "unit": "Pa"}, + "fracture_energy": {"value": 3.8, "unit": "J/m^2"}, + "horizon": {"value": 0.000178, "unit": "m"}, + "traction": {"value": 1e7, "unit": "Pa"}, + "final_time": {"value": 43e-6, "unit": "s"}, + "timestep": {"value": 4.5e-9, "unit": "s"}, + "timestep_safety_factor": {"value": 0.85}, + "output_frequency": {"value": 5}, + "output_reference": {"value": true} +} diff --git a/examples/mechanics/inputs/plate_tension.json b/examples/mechanics/inputs/plate_tension.json new file mode 100644 index 0000000..adb9ef9 --- /dev/null +++ b/examples/mechanics/inputs/plate_tension.json @@ -0,0 +1,14 @@ +{ + "num_cells" : {"value": [848, 848, 17]}, + "system_size" : {"value": [0.05, 0.05, 0.001], "unit": "m"}, + "density" : {"value": 2440.0, "unit": "kg/m^3"}, + "elastic_modulus" : {"value": 200.0e+9, "unit": "Pa"}, + "fracture_energy" : {"value": 500.0, "unit": "J/m^2"}, + "horizon" : {"value": 0.000178, "unit": "m"}, + "traction" : {"value": 1e7, "unit": "Pa"}, + "final_time" : {"value": 43e-6, "unit": "s"}, + "timestep" : {"value": 4.5e-8, "unit": "s"}, + "timestep_safety_factor" : {"value": 0.85}, + "output_frequency" : {"value": 5}, + "output_reference" : {"value": true} +} diff --git a/src/CabanaPD_Force.hpp b/src/CabanaPD_Force.hpp index ea7d87b..a862c89 100644 --- a/src/CabanaPD_Force.hpp +++ b/src/CabanaPD_Force.hpp @@ -137,6 +137,7 @@ class Force Timer _timer; Timer _energy_timer; + Timer _stress_timer; public: using neighbor_list_type = @@ -288,6 +289,22 @@ double computeEnergy( ForceType& force, ParticleType& particles, return energy; } +template +void computeStress( ForceType& force, ParticleType& particles, + const ParallelType& neigh_op_tag ) +{ + if constexpr ( is_stress_output::value ) + { + auto stress = particles.sliceStress(); + + // Reset stress. + Cabana::deep_copy( stress, 0.0 ); + + force.computeStressFull( particles, neigh_op_tag ); + Kokkos::fence(); + } +} + // Forces with bond breaking. template @@ -344,6 +361,22 @@ double computeEnergy( ForceType& force, ParticleType& particles, return energy; } +template +void computeStress( ForceType& force, ParticleType& particles, NeighborView& mu, + const ParallelType& neigh_op_tag ) +{ + if constexpr ( is_stress_output::value ) + { + auto stress = particles.sliceStress(); + + // Reset stress. + Cabana::deep_copy( stress, 0.0 ); + + force.computeStressFull( particles, mu, neigh_op_tag ); + Kokkos::fence(); + } +} } // namespace CabanaPD #endif diff --git a/src/CabanaPD_Particles.hpp b/src/CabanaPD_Particles.hpp index f007ffd..ac78194 100644 --- a/src/CabanaPD_Particles.hpp +++ b/src/CabanaPD_Particles.hpp @@ -447,6 +447,12 @@ class Particles return Cabana::slice<0>( _aosoa_u, "displacements" ); } auto sliceForce() { return _plist_f.slice( CabanaPD::Field::Force() ); } + + auto sliceForce() const + { + return _plist_f.slice( CabanaPD::Field::Force() ); + } + auto sliceForceAtomic() { auto f = sliceForce(); @@ -953,6 +959,107 @@ class Particles aosoa_output_type _aosoa_output; }; +template +class Particles + : public Particles +{ + public: + using self_type = Particles; + using base_type = + Particles; + using thermal_type = typename base_type::thermal_type; + using output_type = EnergyStressOutput; + using memory_space = typename base_type::memory_space; + using base_type::dim; + + using output_types = Cabana::MemberTypes; + using aosoa_output_type = Cabana::AoSoA; + + // Per type. + using base_type::n_types; + + // Simulation total domain. + using base_type::global_mesh_ext; + + // Simulation sub domain (single MPI rank). + using base_type::ghost_mesh_hi; + using base_type::ghost_mesh_lo; + using base_type::local_mesh_ext; + using base_type::local_mesh_hi; + using base_type::local_mesh_lo; + + using base_type::dx; + using base_type::local_grid; + + using base_type::halo_width; + + // Default constructor. + Particles() + : base_type() + { + _aosoa_output = aosoa_output_type( "Particle Stress Output", 0 ); + } + + // Constructor which initializes particles on regular grid. + template + Particles( const ExecSpace& exec_space, std::array low_corner, + std::array high_corner, + const std::array num_cells, const int max_halo_width ) + : base_type( exec_space, low_corner, high_corner, num_cells, + max_halo_width ) + { + _aosoa_output = aosoa_output_type( "Particle Stress Output", + base_type::localOffset() ); + init_output(); + } + + template + void createParticles( Args&&... args ) + { + // Forward arguments to standard or custom particle creation. + base_type::createParticles( std::forward( args )... ); + _aosoa_output.resize( base_type::localOffset() ); + } + + auto sliceStress() { return Cabana::slice<0>( _aosoa_output, "stress" ); } + auto sliceStress() const + { + return Cabana::slice<0>( _aosoa_output, "stress" ); + } + + void resize( int new_local, int new_ghost ) + { + base_type::resize( new_local, new_ghost ); + _aosoa_output.resize( new_local + new_ghost ); + } + + template + void output( const int output_step, const double output_time, + const bool use_reference, OtherFields&&... other ) + { + base_type::output( output_step, output_time, use_reference, + sliceStress(), + std::forward( other )... ); + } + + friend class Comm; + friend class Comm; + friend class Comm; + friend class Comm; + + protected: + void init_output() + { + auto stress = sliceStress(); + Cabana::deep_copy( stress, 0.0 ); + } + + aosoa_output_type _aosoa_output; +}; + template auto createParticles( ExecSpace exec_space, CabanaPD::Inputs inputs, diff --git a/src/CabanaPD_Solver.hpp b/src/CabanaPD_Solver.hpp index af642f5..9e2c6e7 100644 --- a/src/CabanaPD_Solver.hpp +++ b/src/CabanaPD_Solver.hpp @@ -231,6 +231,7 @@ class SolverElastic // Compute initial internal forces and energy. updateForce(); computeEnergy( *force, *particles, neigh_iter_tag() ); + computeStress( *force, *particles, neigh_iter_tag() ); if ( initial_output ) particles->output( 0, 0.0, output_reference ); @@ -366,6 +367,7 @@ class SolverElastic if ( step % output_frequency == 0 ) { auto W = computeEnergy( *force, *particles, neigh_iter_tag() ); + computeStress( *force, *particles, neigh_iter_tag() ); particles->output( step / output_frequency, step * dt, output_reference ); @@ -550,6 +552,7 @@ class SolverFracture // Compute initial internal forces and energy. updateForce(); computeEnergy( *force, *particles, mu, neigh_iter_tag() ); + computeStress( *force, *particles, mu, neigh_iter_tag() ); if ( initial_output ) particles->output( 0, 0.0, output_reference ); @@ -697,6 +700,7 @@ class SolverFracture if ( step % output_frequency == 0 ) { auto W = computeEnergy( *force, *particles, mu, neigh_iter_tag() ); + computeStress( *force, *particles, mu, neigh_iter_tag() ); particles->output( step / output_frequency, step * dt, output_reference ); diff --git a/src/CabanaPD_Types.hpp b/src/CabanaPD_Types.hpp index fa82092..7a673b5 100644 --- a/src/CabanaPD_Types.hpp +++ b/src/CabanaPD_Types.hpp @@ -88,6 +88,9 @@ struct BaseOutput struct EnergyOutput { }; +struct EnergyStressOutput +{ +}; template struct is_energy_output : public std::false_type @@ -97,6 +100,19 @@ template <> struct is_energy_output : public std::true_type { }; +template <> +struct is_energy_output : public std::true_type +{ +}; + +template +struct is_stress_output : public std::false_type +{ +}; +template <> +struct is_stress_output : public std::true_type +{ +}; } // namespace CabanaPD #endif diff --git a/src/force/CabanaPD_Force_LPS.hpp b/src/force/CabanaPD_Force_LPS.hpp index 9091615..6cc074e 100644 --- a/src/force/CabanaPD_Force_LPS.hpp +++ b/src/force/CabanaPD_Force_LPS.hpp @@ -79,6 +79,7 @@ class Force> ForceModel _model; using base_type::_energy_timer; + using base_type::_stress_timer; using base_type::_timer; public: @@ -256,6 +257,61 @@ class Force> auto time() { return _timer.time(); }; auto timeEnergy() { return _energy_timer.time(); }; + + template + void computeStressFull( ParticleType& particles, + ParallelType& neigh_op_tag ) + { + _stress_timer.start(); + + auto model = _model; + auto neigh_list = _neigh_list; + const auto x = particles.sliceReferencePosition(); + const auto u = particles.sliceDisplacement(); + const auto vol = particles.sliceVolume(); + const auto theta = particles.sliceDilatation(); + const auto m = particles.sliceWeightedVolume(); + auto stress = particles.sliceStress(); + + auto stress_full = KOKKOS_LAMBDA( const int i, const int j ) + { + double xi, r, s; + double rx, ry, rz; + getDistanceComponents( x, u, i, j, xi, r, s, rx, ry, rz ); + + const double coeff = + ( model.theta_coeff * + ( theta( i ) / m( i ) + theta( j ) / m( j ) ) + + model.s_coeff * s * ( 1.0 / m( i ) + 1.0 / m( j ) ) ) * + model.influence_function( xi ) * xi * vol( j ) * vol( j ); + + double fx_i = coeff * rx / r; + double fy_i = coeff * ry / r; + double fz_i = coeff * rz / r; + + // Update stress tensor components + stress( i, 0, 0 ) += fx_i * rx; + stress( i, 1, 1 ) += fy_i * ry; + stress( i, 2, 2 ) += fz_i * rz; + + stress( i, 0, 1 ) += fx_i * ry; + stress( i, 1, 0 ) += fy_i * rx; + + stress( i, 0, 2 ) += fx_i * rz; + stress( i, 2, 0 ) += fz_i * rx; + + stress( i, 1, 2 ) += fy_i * rz; + stress( i, 2, 1 ) += fz_i * ry; + }; + + Kokkos::RangePolicy policy( particles.frozenOffset(), + particles.localOffset() ); + Cabana::neighbor_parallel_for( + policy, stress_full, _neigh_list, Cabana::FirstNeighborsTag(), + neigh_op_tag, "CabanaPD::ForceLPSFracture::computeStressFull" ); + + _stress_timer.stop(); + } }; template @@ -268,6 +324,7 @@ class Force> ForceModel _model; using base_type::_energy_timer; + using base_type::_stress_timer; using base_type::_timer; public: @@ -508,6 +565,76 @@ class Force> _energy_timer.stop(); return strain_energy; } + + template + void computeStressFull( ParticleType& particles, const MuView& mu, + ParallelType& ) + { + _stress_timer.start(); + + auto model = _model; + auto neigh_list = _neigh_list; + const auto x = particles.sliceReferencePosition(); + const auto u = particles.sliceDisplacement(); + const auto vol = particles.sliceVolume(); + const auto theta = particles.sliceDilatation(); + const auto m = particles.sliceWeightedVolume(); + auto stress = particles.sliceStress(); + + auto stress_full = KOKKOS_LAMBDA( const int i ) + { + std::size_t num_neighbors = + Cabana::NeighborList::numNeighbor( + neigh_list, i ); + for ( std::size_t n = 0; n < num_neighbors; n++ ) + { + std::size_t j = + Cabana::NeighborList::getNeighbor( + neigh_list, i, n ); + + if ( mu( i, n ) > 0 ) // Only compute stress for unbroken bonds + { + double xi, r, s; + double rx, ry, rz; + getDistanceComponents( x, u, i, j, xi, r, s, rx, ry, rz ); + + const double coeff = + ( model.theta_coeff * + ( theta( i ) / m( i ) + theta( j ) / m( j ) ) + + model.s_coeff * s * + ( 1.0 / m( i ) + 1.0 / m( j ) ) ) * + model.influence_function( xi ) * xi * vol( j ) * + vol( j ); + + double muij = mu( i, n ); + double fx_i = muij * coeff * rx / r; + double fy_i = muij * coeff * ry / r; + double fz_i = muij * coeff * rz / r; + + // Update stress tensor components + stress( i, 0, 0 ) += fx_i * rx; + stress( i, 1, 1 ) += fy_i * ry; + stress( i, 2, 2 ) += fz_i * rz; + + stress( i, 0, 1 ) += fx_i * ry; + stress( i, 1, 0 ) += fy_i * rx; + + stress( i, 0, 2 ) += fx_i * rz; + stress( i, 2, 0 ) += fz_i * rx; + + stress( i, 1, 2 ) += fy_i * rz; + stress( i, 2, 1 ) += fz_i * ry; + } + } + }; + + Kokkos::RangePolicy policy( particles.frozenOffset(), + particles.localOffset() ); + Kokkos::parallel_for( "CabanaPD::ForceLPSFracture::computeStressFull", + policy, stress_full ); + + _stress_timer.stop(); + } }; template @@ -519,6 +646,7 @@ class Force> ForceModel _model; using base_type::_energy_timer; + using base_type::_stress_timer; using base_type::_timer; public: @@ -637,6 +765,63 @@ class Force> _energy_timer.stop(); return strain_energy; } + + template + void computeStressFull( ParticleType& particles, + ParallelType& neigh_op_tag ) + { + _stress_timer.start(); + + auto model = _model; + auto neigh_list = _neigh_list; + const auto x = particles.sliceReferencePosition(); + const auto u = particles.sliceDisplacement(); + const auto vol = particles.sliceVolume(); + const auto theta = particles.sliceDilatation(); + const auto m = particles.sliceWeightedVolume(); + auto stress = particles.sliceStress(); + + auto stress_full = KOKKOS_LAMBDA( const int i, const int j ) + { + // Get the bond distance, displacement, and stretch + double xi, r, s; + double rx, ry, rz; + getLinearizedDistanceComponents( x, u, i, j, xi, r, s, rx, ry, rz ); + + // LPS specific coefficients + const double coeff = + ( model.theta_coeff * + ( theta( i ) / m( i ) + theta( j ) / m( j ) ) + + model.s_coeff * s * ( 1.0 / m( i ) + 1.0 / m( j ) ) ) * + model.influence_function( xi ) * xi * vol( j ) * vol( j ); + + double fx_i = coeff * rx / r; + double fy_i = coeff * ry / r; + double fz_i = coeff * rz / r; + + // Update stress tensor components + stress( i, 0, 0 ) += fx_i * rx; + stress( i, 1, 1 ) += fy_i * ry; + stress( i, 2, 2 ) += fz_i * rz; + + stress( i, 0, 1 ) += fx_i * ry; + stress( i, 1, 0 ) += fy_i * rx; + + stress( i, 0, 2 ) += fx_i * rz; + stress( i, 2, 0 ) += fz_i * rx; + + stress( i, 1, 2 ) += fy_i * rz; + stress( i, 2, 1 ) += fz_i * ry; + }; + + Kokkos::RangePolicy policy( particles.frozenOffset(), + particles.localOffset() ); + Cabana::neighbor_parallel_for( + policy, stress_full, _neigh_list, Cabana::FirstNeighborsTag(), + neigh_op_tag, "CabanaPD::ForceLPS::computeStressFull" ); + + _stress_timer.stop(); + } }; } // namespace CabanaPD diff --git a/src/force/CabanaPD_Force_PMB.hpp b/src/force/CabanaPD_Force_PMB.hpp index 5d6cd2a..1063adb 100644 --- a/src/force/CabanaPD_Force_PMB.hpp +++ b/src/force/CabanaPD_Force_PMB.hpp @@ -87,6 +87,7 @@ class Force> model_type _model; using base_type::_energy_timer; + using base_type::_stress_timer; using base_type::_timer; public: @@ -178,6 +179,56 @@ class Force> _energy_timer.stop(); return strain_energy; } + + template + void computeStressFull( ParticleType& particles, + ParallelType& neigh_op_tag ) + { + _stress_timer.start(); + + auto model = _model; + const auto x = particles.sliceReferencePosition(); + const auto u = particles.sliceDisplacement(); + const auto vol = particles.sliceVolume(); + const auto f = particles.sliceForce(); + auto stress = particles.sliceStress(); + + auto stress_full = KOKKOS_LAMBDA( const int i, const int j ) + { + // Get the bond distance, displacement, and stretch. + double xi, r, s; + double rx, ry, rz; + getDistanceComponents( x, u, i, j, xi, r, s, rx, ry, rz ); + + model.thermalStretch( s, i, j ); + + const double coeff = 0.5 * model.c * s * vol( j ) * vol( j ); + double fx_i = coeff * rx / r; + double fy_i = coeff * ry / r; + double fz_i = coeff * rz / r; + + stress( i, 0, 0 ) += fx_i * rx; + stress( i, 1, 1 ) += fy_i * ry; + stress( i, 2, 2 ) += fz_i * rz; + + stress( i, 0, 1 ) += fx_i * ry; + stress( i, 1, 0 ) += fy_i * rx; + + stress( i, 0, 2 ) += fx_i * rz; + stress( i, 2, 0 ) += fz_i * rx; + + stress( i, 1, 2 ) += fy_i * rz; + stress( i, 2, 1 ) += fz_i * ry; + }; + + Kokkos::RangePolicy policy( particles.frozenOffset(), + particles.localOffset() ); + Cabana::neighbor_parallel_for( + policy, stress_full, _neigh_list, Cabana::FirstNeighborsTag(), + neigh_op_tag, "CabanaPD::ForcePMB::computeStressFull" ); + + _stress_timer.stop(); + } }; template @@ -198,6 +249,7 @@ class Force> model_type _model; using base_type::_energy_timer; + using base_type::_stress_timer; using base_type::_timer; public: @@ -325,6 +377,65 @@ class Force> _energy_timer.stop(); return strain_energy; } + + template + void computeStressFull( ParticleType& particles, MuView& mu, ParallelType& ) + { + _stress_timer.start(); + + auto model = _model; + auto neigh_list = _neigh_list; + const auto x = particles.sliceReferencePosition(); + const auto u = particles.sliceDisplacement(); + const auto vol = particles.sliceVolume(); + const auto f = particles.sliceForce(); + auto stress = particles.sliceStress(); + + auto stress_full = KOKKOS_LAMBDA( const int i ) + { + std::size_t num_neighbors = + Cabana::NeighborList::numNeighbor( + neigh_list, i ); + for ( std::size_t n = 0; n < num_neighbors; n++ ) + { + std::size_t j = + Cabana::NeighborList::getNeighbor( + neigh_list, i, n ); + // Get the bond distance, displacement, and stretch. + double xi, r, s; + double rx, ry, rz; + getDistanceComponents( x, u, i, j, xi, r, s, rx, ry, rz ); + + model.thermalStretch( s, i, j ); + + const double coeff = + mu( i, n ) * 0.5 * model.c * s * vol( j ) * vol( j ); + double fx_i = coeff * rx / r; + double fy_i = coeff * ry / r; + double fz_i = coeff * rz / r; + + stress( i, 0, 0 ) += fx_i * rx; + stress( i, 1, 1 ) += fy_i * ry; + stress( i, 2, 2 ) += fz_i * rz; + + stress( i, 0, 1 ) += fx_i * ry; + stress( i, 1, 0 ) += fy_i * rx; + + stress( i, 0, 2 ) += fx_i * rz; + stress( i, 2, 0 ) += fz_i * rx; + + stress( i, 1, 2 ) += fy_i * rz; + stress( i, 2, 1 ) += fz_i * ry; + } + }; + + Kokkos::RangePolicy policy( particles.frozenOffset(), + particles.localOffset() ); + Kokkos::parallel_for( "CabanaPD::ForcePMBDamage::computeStressFull", + policy, stress_full ); + + _stress_timer.stop(); + } }; template @@ -344,6 +455,7 @@ class Force> model_type _model; using base_type::_energy_timer; + using base_type::_stress_timer; using base_type::_timer; public: @@ -401,7 +513,7 @@ class Force> template double computeEnergyFull( WType& W, const PosType& x, const PosType& u, - ParticleType& particles, + const ParticleType& particles, ParallelType& neigh_op_tag ) { _energy_timer.start(); @@ -436,6 +548,58 @@ class Force> _energy_timer.stop(); return strain_energy; } + + template + void computeStressFull( ParticleType& particles, + ParallelType& neigh_op_tag ) + { + _stress_timer.start(); + + auto model = _model; + auto neigh_list = _neigh_list; + const auto x = particles.sliceReferencePosition(); + const auto u = particles.sliceDisplacement(); + const auto vol = particles.sliceVolume(); + auto stress = particles.sliceStress(); + + auto stress_full = KOKKOS_LAMBDA( const int i, const int j ) + { + // Get the bond distance, displacement, and stretch + double xi, r, s; + double rx, ry, rz; + getLinearizedDistanceComponents( x, u, i, j, xi, r, s, rx, ry, rz ); + + model.thermalStretch( s, i, j ); + + // Linear PMB specific coefficient + const double coeff = 0.5 * model.c * s * vol( j ) * vol( j ); + double fx_i = coeff * rx / r; + double fy_i = coeff * ry / r; + double fz_i = coeff * rz / r; + + // Update stress tensor components + stress( i, 0, 0 ) += fx_i * rx; + stress( i, 1, 1 ) += fy_i * ry; + stress( i, 2, 2 ) += fz_i * rz; + + stress( i, 0, 1 ) += fx_i * ry; + stress( i, 1, 0 ) += fy_i * rx; + + stress( i, 0, 2 ) += fx_i * rz; + stress( i, 2, 0 ) += fz_i * rx; + + stress( i, 1, 2 ) += fy_i * rz; + stress( i, 2, 1 ) += fz_i * ry; + }; + + Kokkos::RangePolicy policy( particles.frozenOffset(), + particles.localOffset() ); + Cabana::neighbor_parallel_for( + policy, stress_full, _neigh_list, Cabana::FirstNeighborsTag(), + neigh_op_tag, "CabanaPD::ForceLinearPMB::computeStressFull" ); + + _stress_timer.stop(); + } }; } // namespace CabanaPD