diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..344b91d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,31 @@
+*.txt
+*.err
+*.rat
+*.tsl
+*.wel
+*.out
+*.log
+*.exe*
+*.dll*
+*.htm*
+*.obj
+*.pch*
+*.dep
+*.idb
+*.pdb
+*.pyc
+*.rst
+*.ncb
+*.suo
+*.user
+*.orig
+blue-sky
+*.dblite
+.debug
+.release
+*.os
+*.obj
+*.png
+*.csv
+callgrind*
+tags
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..3a7974a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2009, The BS Eagle Project.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the BS Eagle Project nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/README b/README
new file mode 100644
index 0000000..2c751c8
--- /dev/null
+++ b/README
@@ -0,0 +1,30 @@
+BS Eagle black-oil simulator
+
+The BS Eagle Project (bs-eagle) is an open source black-oil simulator.
+The main goal of this project is to provide a free access to the state
+of the art oil simulation software to study new methods of oil's
+simulation.
+
+The project based on a BlueSky integration platform and
+has a modular architecture and open to modifications and extensions.
+
+Current available plugins are:
+ - linear solvers (gmres, cgs, tfqmr, bicgstab, csr_ilu_prec)
+ - data storages (hdf5)
+ - grids (ijk, eclipse)
+ - wells (full implicit black oil model)
+ - jacobian's fillers
+ - array arithmetics
+
+To build bs-eagle you need:
+ 1. BlueSky kernel
+ 2. Python 2.5
+ 3. SCons (or MS Visual Studio 2005)
+ 4. Boost library, recomended version is 1.39
+ 5. Loki library, recomended version 0.1.6
+ 6. HDF5 library, recomnded version 1.8.3
+ 6.1. SZIP, recomnded version 2.1
+ 6.2. ZLIB, recomnded version 1.2
+
+Example of BlueSky BuildSystem script placed at
+examples/scons_env.custom and examples/scons_vars.custom.
diff --git a/SConscript b/SConscript
new file mode 100644
index 0000000..10a2238
--- /dev/null
+++ b/SConscript
@@ -0,0 +1,9 @@
+SConscript ("bs_bos_core_base/SConscript.bs")
+SConscript ("bs_matrix/SConscript.bs")
+SConscript ("bs_base_linear_solvers/SConscript.bs")
+SConscript ("bs_csr_ilu_prec/SConscript.bs")
+SConscript ("bs_bos_core_data_storage/SConscript.bs")
+SConscript ("bs_mesh/SConscript.bs")
+SConscript ("bs_scal/SConscript.bs")
+SConscript ("bs_pvt/SConscript.bs")
+SConscript ("bs_bos_core/SConscript.bs")
diff --git a/all.sln b/all.sln
new file mode 100644
index 0000000..46703df
--- /dev/null
+++ b/all.sln
@@ -0,0 +1,295 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_bos_core", "bs_bos_core\bs_bos_core.vcproj", "{B096BE31-726C-42A6-AFB0-C6BADE241F0D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {6179CF48-524A-4031-993A-FD353AD2A74F} = {6179CF48-524A-4031-993A-FD353AD2A74F}
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652} = {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D} = {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}
+ {952339F0-0C05-440C-8168-A8C2C463D3AE} = {952339F0-0C05-440C-8168-A8C2C463D3AE}
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89} = {CE770FDD-686B-48FB-9DFA-B660196BEF89}
+ {0EE477D9-9766-4B63-A50F-6778116CF649} = {0EE477D9-9766-4B63-A50F-6778116CF649}
+ {578A43D7-0338-4ED0-A455-666FDA782085} = {578A43D7-0338-4ED0-A455-666FDA782085}
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C} = {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81} = {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}
+ {25D48348-7171-4ED5-8AE9-166C23CAC051} = {25D48348-7171-4ED5-8AE9-166C23CAC051}
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57} = {E7322907-2C9C-4570-A99E-A2F3E56A3D57}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blue-sky", "..\..\kernel\blue-sky.vcproj", "{7C235C2A-609A-49B4-A89B-AC23530F0F89}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bspy_loader", "..\..\python\bspy_loader\bspy_loader.vcproj", "{5FC52CB5-D666-4608-A354-81E3B5DE6035}"
+ ProjectSection(ProjectDependencies) = postProject
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89} = {7C235C2A-609A-49B4-A89B-AC23530F0F89}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_matrix", "bs_matrix\bs_matrix.vcproj", "{AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {578A43D7-0338-4ED0-A455-666FDA782085} = {578A43D7-0338-4ED0-A455-666FDA782085}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_base_linear_solvers", "bs_base_linear_solvers\bs_base_linear_solvers.vcproj", "{0EE477D9-9766-4B63-A50F-6778116CF649}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D} = {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_bos_core_base", "bs_bos_core_base\bs_bos_core_base.vcproj", "{578A43D7-0338-4ED0-A455-666FDA782085}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035} = {5FC52CB5-D666-4608-A354-81E3B5DE6035}
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89} = {7C235C2A-609A-49B4-A89B-AC23530F0F89}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_amg_solver", "..\bs_amg_solver\bs_amg_solver.vcproj", "{952339F0-0C05-440C-8168-A8C2C463D3AE}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0EE477D9-9766-4B63-A50F-6778116CF649} = {0EE477D9-9766-4B63-A50F-6778116CF649}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_cpr_prec", "..\bs_cpr_prec\bs_cpr_prec.vcproj", "{25D48348-7171-4ED5-8AE9-166C23CAC051}"
+ ProjectSection(ProjectDependencies) = postProject
+ {952339F0-0C05-440C-8168-A8C2C463D3AE} = {952339F0-0C05-440C-8168-A8C2C463D3AE}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_csr_ilu_prec", "bs_csr_ilu_prec\bs_csr_ilu_prec.vcproj", "{AAF02BD1-4A63-428B-8FC3-275C2ED1337C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0EE477D9-9766-4B63-A50F-6778116CF649} = {0EE477D9-9766-4B63-A50F-6778116CF649}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_mesh", "bs_mesh\bs_mesh.vcproj", "{CE770FDD-686B-48FB-9DFA-B660196BEF89}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81} = {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_bos_core_data_storage", "bs_bos_core_data_storage\bs_bos_core_data_storage.vcproj", "{3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D} = {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}
+ {578A43D7-0338-4ED0-A455-666FDA782085} = {578A43D7-0338-4ED0-A455-666FDA782085}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_pvt", "bs_pvt\bs_pvt.vcproj", "{32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}"
+ ProjectSection(ProjectDependencies) = postProject
+ {6179CF48-524A-4031-993A-FD353AD2A74F} = {6179CF48-524A-4031-993A-FD353AD2A74F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_scal", "bs_scal\bs_scal.vcproj", "{6179CF48-524A-4031-993A-FD353AD2A74F}"
+ ProjectSection(ProjectDependencies) = postProject
+ {578A43D7-0338-4ED0-A455-666FDA782085} = {578A43D7-0338-4ED0-A455-666FDA782085}
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D} = {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_mswell", "..\bs_mswell\bs_mswell\bs_mswell.vcproj", "{F73A1821-6C19-451F-A1DF-D4A4862D5E1F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_hdf5_storage", "..\bs_hdf5_storage\bs_hdf5_storage.vcproj", "{E7322907-2C9C-4570-A99E-A2F3E56A3D57}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D} = {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_mesh_mpfa", "..\bs_mesh_mpfa\bs_mesh_mpfa.vcproj", "{9A036071-A4DB-4609-9B59-727AA3D49B24}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89} = {CE770FDD-686B-48FB-9DFA-B660196BEF89}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_HDF5|Win32 = Debug_HDF5|Win32
+ Debug_MPI|Win32 = Debug_MPI|Win32
+ Debug|Win32 = Debug|Win32
+ Release_HDF5|Win32 = Release_HDF5|Win32
+ release_with_debug|Win32 = release_with_debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Debug_HDF5|Win32.ActiveCfg = Debug_HDF5|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Debug_HDF5|Win32.Build.0 = Debug_HDF5|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Debug_MPI|Win32.ActiveCfg = Debug_MPI|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Debug_MPI|Win32.Build.0 = Debug_MPI|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Debug|Win32.Build.0 = Debug|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Release_HDF5|Win32.ActiveCfg = Release_HDF5|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Release_HDF5|Win32.Build.0 = Release_HDF5|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.release_with_debug|Win32.Build.0 = Release|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Release|Win32.ActiveCfg = Release|Win32
+ {B096BE31-726C-42A6-AFB0-C6BADE241F0D}.Release|Win32.Build.0 = Release|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Debug|Win32.Build.0 = Debug|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.release_with_debug|Win32.ActiveCfg = release_with_debug|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.release_with_debug|Win32.Build.0 = release_with_debug|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Release|Win32.ActiveCfg = Release|Win32
+ {7C235C2A-609A-49B4-A89B-AC23530F0F89}.Release|Win32.Build.0 = Release|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Debug|Win32.Build.0 = Debug|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.release_with_debug|Win32.Build.0 = Release|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Release|Win32.ActiveCfg = Release|Win32
+ {5FC52CB5-D666-4608-A354-81E3B5DE6035}.Release|Win32.Build.0 = Release|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Debug|Win32.Build.0 = Debug|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.release_with_debug|Win32.Build.0 = Release|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Release|Win32.ActiveCfg = Release|Win32
+ {AAB3AFFB-CBD4-4367-BFA2-76C656498E6D}.Release|Win32.Build.0 = Release|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Debug|Win32.Build.0 = Debug|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.release_with_debug|Win32.Build.0 = Release|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Release|Win32.ActiveCfg = Release|Win32
+ {0EE477D9-9766-4B63-A50F-6778116CF649}.Release|Win32.Build.0 = Release|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Debug|Win32.ActiveCfg = Debug|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Debug|Win32.Build.0 = Debug|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.release_with_debug|Win32.Build.0 = Release|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Release|Win32.ActiveCfg = Release|Win32
+ {578A43D7-0338-4ED0-A455-666FDA782085}.Release|Win32.Build.0 = Release|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Debug|Win32.Build.0 = Debug|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.release_with_debug|Win32.Build.0 = Release|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Release|Win32.ActiveCfg = Release|Win32
+ {952339F0-0C05-440C-8168-A8C2C463D3AE}.Release|Win32.Build.0 = Release|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Debug|Win32.ActiveCfg = Debug|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Debug|Win32.Build.0 = Debug|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.release_with_debug|Win32.Build.0 = Release|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Release|Win32.ActiveCfg = Release|Win32
+ {25D48348-7171-4ED5-8AE9-166C23CAC051}.Release|Win32.Build.0 = Release|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Debug|Win32.Build.0 = Debug|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.release_with_debug|Win32.Build.0 = Release|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Release|Win32.ActiveCfg = Release|Win32
+ {AAF02BD1-4A63-428B-8FC3-275C2ED1337C}.Release|Win32.Build.0 = Release|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Debug|Win32.Build.0 = Debug|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.release_with_debug|Win32.Build.0 = Release|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Release|Win32.ActiveCfg = Release|Win32
+ {CE770FDD-686B-48FB-9DFA-B660196BEF89}.Release|Win32.Build.0 = Release|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Debug|Win32.Build.0 = Debug|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.release_with_debug|Win32.Build.0 = Release|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Release|Win32.ActiveCfg = Release|Win32
+ {3DF8BD9D-CAEF-4081-A1C2-B624E0959A81}.Release|Win32.Build.0 = Release|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Debug|Win32.ActiveCfg = Debug|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Debug|Win32.Build.0 = Debug|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.release_with_debug|Win32.Build.0 = Release|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Release|Win32.ActiveCfg = Release|Win32
+ {32C5BEFC-9E7D-4341-ACD4-DDDCFEB77652}.Release|Win32.Build.0 = Release|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Debug|Win32.Build.0 = Debug|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.release_with_debug|Win32.Build.0 = Release|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Release|Win32.ActiveCfg = Release|Win32
+ {6179CF48-524A-4031-993A-FD353AD2A74F}.Release|Win32.Build.0 = Release|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.Debug|Win32.Build.0 = Debug|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.release_with_debug|Win32.Build.0 = Release|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.Release|Win32.ActiveCfg = Release|Win32
+ {F73A1821-6C19-451F-A1DF-D4A4862D5E1F}.Release|Win32.Build.0 = Release|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Debug|Win32.Build.0 = Debug|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.release_with_debug|Win32.Build.0 = Release|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Release|Win32.ActiveCfg = Release|Win32
+ {E7322907-2C9C-4570-A99E-A2F3E56A3D57}.Release|Win32.Build.0 = Release|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Debug_HDF5|Win32.ActiveCfg = Debug|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Debug_HDF5|Win32.Build.0 = Debug|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Debug_MPI|Win32.ActiveCfg = Debug|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Debug_MPI|Win32.Build.0 = Debug|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Debug|Win32.Build.0 = Debug|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Release_HDF5|Win32.ActiveCfg = Release|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Release_HDF5|Win32.Build.0 = Release|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.release_with_debug|Win32.ActiveCfg = Release|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.release_with_debug|Win32.Build.0 = Release|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Release|Win32.ActiveCfg = Release|Win32
+ {9A036071-A4DB-4609-9B59-727AA3D49B24}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/bs_base_linear_solvers/SConscript.bs b/bs_base_linear_solvers/SConscript.bs
new file mode 100644
index 0000000..5e1e9a0
--- /dev/null
+++ b/bs_base_linear_solvers/SConscript.bs
@@ -0,0 +1,28 @@
+import os
+Import ("*")
+
+lib_name = "bs_base_linear_solvers"
+tar_name = "bs_base_linear_solvers"
+
+env = custom_env.Clone ()
+env.Append (CPPPATH = ["include",
+ includes["bs_bos_core_base"],
+ includes["bs_matrix"]
+ ] + includes["kernel"])
+
+libs = ["blue_sky", "bs_bos_core_base", "bs_matrix"]
+
+if (build_kind == "debug") :
+ env.AppendUnique (LIBS = list_suffix (libs, "_d"))
+ lib_name += "_d"
+elif (build_kind == "release") :
+ env.AppendUnique (LIBS = libs)
+
+bs_base_linear_solvers = env.SharedLibrary (target = os.path.join (tar_exe_plugin_dir, lib_name), source = files (["."]).sources)
+
+env.Alias (tar_name, bs_base_linear_solvers)
+Export ("bs_base_linear_solvers")
+
+if (env["install"] == 1) :
+ inst_tar = env.Install ("$plugins_prefix", bs_base_linear_solvers)
+ env.Alias (tar_name, inst_tar)
diff --git a/bs_base_linear_solvers/bs_base_linear_solvers.vcproj b/bs_base_linear_solvers/bs_base_linear_solvers.vcproj
new file mode 100644
index 0000000..d064b69
--- /dev/null
+++ b/bs_base_linear_solvers/bs_base_linear_solvers.vcproj
@@ -0,0 +1,277 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bs_base_linear_solvers/include/bs_base_linear_solvers_stdafx.h b/bs_base_linear_solvers/include/bs_base_linear_solvers_stdafx.h
new file mode 100644
index 0000000..05f41ea
--- /dev/null
+++ b/bs_base_linear_solvers/include/bs_base_linear_solvers_stdafx.h
@@ -0,0 +1,87 @@
+/**
+* \file stdafx.h
+* \brief precompiled header
+* \author Sergey Miryanov
+* */
+#ifndef BS_BASE_LINEAR_SOLVERS_PRECOMPILED_HEADERS_H_
+#define BS_BASE_LINEAR_SOLVERS_PRECOMPILED_HEADERS_H_
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows XP or later.
+#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
+#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
+#endif
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+#ifndef UNIX
+#include
+#else
+#include
+#endif
+
+#include
+
+#include
+
+#include "bs_common.h"
+#include BS_FORCE_PLUGIN_IMPORT ()
+#include "smart_ptr.h"
+#include "bs_kernel.h"
+#include "bs_link.h"
+#include "bs_object_base.h"
+#include "bs_tree.h"
+#include "bs_exception.h"
+#include "bs_prop_base.h"
+#include BS_STOP_PLUGIN_IMPORT ()
+
+#ifdef BSPY_EXPORTING_PLUGIN
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include BS_FORCE_PLUGIN_IMPORT ()
+#include "bs_plugin_common.h"
+#include "py_bs_object_base.h"
+#include "py_bs_command.h"
+#include "py_bs_tree.h"
+#include BS_STOP_PLUGIN_IMPORT ()
+#endif
+
+#include BS_FORCE_PLUGIN_IMPORT ()
+#include "force_inline.h"
+#include "bs_assert.h"
+#include "bos_report.h"
+
+#include "aligned_allocator.h"
+#include "strategies.h"
+
+#include "omp_tools.h"
+#include "mv_tools.h"
+
+#include "py_bcsr_matrix.h"
+#include "write_time_to_log.h"
+#include "dummy_base.h"
+#include "named_pbase_access.h"
+#include "throw_exception.h"
+#include BS_STOP_PLUGIN_IMPORT ()
+
+#endif // #ifndef BS_BASE_LINEAR_SOLVERS_PRECOMPILED_HEADERS_H_
diff --git a/bs_base_linear_solvers/include/cgs.h b/bs_base_linear_solvers/include/cgs.h
new file mode 100644
index 0000000..523519c
--- /dev/null
+++ b/bs_base_linear_solvers/include/cgs.h
@@ -0,0 +1,82 @@
+/**
+ * \file cgs.h
+ * \brief CGS linear solver
+ * \author SalimgareevaEM
+ * \date
+ * */
+#ifndef BS_CGS_LINEAR_SOLVER_H_
+#define BS_CGS_LINEAR_SOLVER_H_
+
+#include "linear_solvers.h"
+
+namespace blue_sky
+ {
+ /**
+ * @brief CGS linear solver
+ */
+ template
+ class BS_API_PLUGIN cgs_solver : public linear_solver_base
+ {
+
+ //-----------------------------------------
+ // TYPES
+ //-----------------------------------------
+ public:
+ typedef typename strategy_t::matrix_t matrix_t; ///< short name to matrix type
+ typedef typename strategy_t::item_array_t item_array_t; ///< short name to array type
+ typedef typename strategy_t::item_t item_t; ///< short name to array item type
+ typedef typename strategy_t::index_t index_t; ///< short name to matrix's index type
+ typedef typename strategy_t::rhs_item_t rhs_item_t; ///< short name for type of rhs
+ typedef typename strategy_t::rhs_item_array_t rhs_item_array_t; ///< short name for rhs array type
+
+
+ typedef typename strategy_t::matrix_array_t matrix_array_t; ///< short name to matrix array type
+
+ typedef typename strategy_t::index_array_t index_array_t;
+
+ typedef linear_solver_base this_t; ///< typedef to this type
+ typedef linear_solver_base base_t; ///< typedef to this type. in child classes used as a short name of base class
+ typedef smart_ptr sp_this_t; ///< short name to smart pointer to this class
+ typedef smart_ptr sp_prop_t; ///< short name to smart pointer to properties holder class
+
+ typedef smart_ptr sp_matrix_t; ///< short name to smart pointer on matrix_t
+
+ typedef bcsr_matrix bcsr_matrix_t; ///< short name for used matrix
+ typedef smart_ptr sp_bcsr_matrix_t; ///< short name for smart_pointer on used matrix
+
+ //-----------------------------------------
+ // METHODS
+ //-----------------------------------------
+ public:
+ //! destructor
+ virtual ~cgs_solver ();
+
+ //! solve
+ virtual int solve (matrix_t *matrix, rhs_item_array_t &rhs, item_array_t &sol);
+
+ virtual int solve_prec (matrix_t *matrix, item_array_t &rhs, item_array_t &sol);
+
+ //! setup
+ virtual int setup (matrix_t *matrix);
+
+ //template
+ //int init_by_matrix (const mx_t *mx);
+
+ template
+ int
+ templ_solve (matrix_t *matrix, rhs_t &rhs, item_array_t &sol);
+
+ private:
+ //-----------------------------------------
+ // VARIABLES
+ //-----------------------------------------
+ public:
+
+ public:
+ BLUE_SKY_TYPE_DECL (cgs_solver);
+ };
+
+ } // namespace blue_sky
+
+#endif // #ifndef BS_CGS_LINEAR_SOLVER_H_
+
diff --git a/bs_base_linear_solvers/include/lin_solv_macro.h b/bs_base_linear_solvers/include/lin_solv_macro.h
new file mode 100644
index 0000000..2659790
--- /dev/null
+++ b/bs_base_linear_solvers/include/lin_solv_macro.h
@@ -0,0 +1,169 @@
+/**
+ * \file lin_solv_macro.h
+ * \brief
+ * \author
+ * \date
+ * */
+#ifndef BS_LIN_SOLV_MACRO_H_
+#define BS_LIN_SOLV_MACRO_H_
+
+namespace blue_sky
+ {
+ /**
+ * @brief sum vector
+ *
+ * @param A -- first vector
+ * @param B -- second vector
+ * @param alpha -- first scalar
+ * @param beta -- second scalar
+ * @param RES -- result vector
+ * @param I -- index
+ * @param N -- vector length
+
+ *
+ * @return nothing
+ */
+ #define SUM_VECTOR(A,B,alpha,beta,RES,I,N) \
+ for ((I) = 0; (I) < (N); ++(I)) \
+ (RES)[(I)] = alpha*(A)[(I)] + beta*(B)[(I)];
+
+ template
+ inline void sum_vector (vector_t &x, typename vector_t::value_type alpha, vector_t &y, typename vector_t::value_type beta, vector_t &res)
+ {
+ //int i = 0, cnt = (int)a.size ();
+
+ #ifdef GMRES_SOLVER2_SOLVE_PARALLEL
+ #pragma omp parallel for
+ #endif
+ BS_ASSERT (x.size ());
+ BS_ASSERT (y.size ());
+ BS_ASSERT (res.size ());
+ BS_ASSERT (x.size () == y.size ());
+ BS_ASSERT (x.size () == res.size ());
+
+ size_t i = 0, cnt = x.size ();
+
+ for (i = 0; i < cnt; ++i)
+ {
+ res[i] = alpha * x[i] + beta * y[i];
+ }
+ }
+
+
+
+
+ /**
+ * @brief scale vector
+ *
+ * @param A -- vector
+ * @param T -- scale factor
+ * @param I -- index
+ * @param N -- vector length
+ *
+ * @return nothing
+ */
+ #define SCALE_VECTOR(A,T,I,N) \
+ for ((I) = 0; (I) < (N); ++(I)) \
+ (A)[(I)] *= (T);
+
+ // if we got performance decrease we have to specify macroses for seq and mpi separately
+ // used only in gmres_solver2
+ template
+ inline void scale_vector (vector_t &a, typename vector_t::value_type t)
+ {
+ int i = 0, cnt = (int)a.size ();
+
+ #ifdef GMRES_SOLVER2_SOLVE_PARALLEL
+ #pragma omp parallel for
+ #endif
+ for (i = 0; i < cnt; ++i)
+ {
+ a[i] *= t;
+ }
+ }
+
+ /**
+ * @brief AXPY (X = X + T * Y)
+ *
+ * @param X -- vector
+ * @param T -- scale factor
+ * @param Y -- vector
+ * @param I -- index
+ * @param N -- vectors length
+ *
+ * @return nothing
+ */
+ #define AXPY(X,T,Y,I,N) \
+ for ((I) = 0; (I) < (N); ++(I)) \
+ (X)[(I)] += (T) * (Y)[(I)];
+
+ // if we get performance decrease we have to specify macroses for seq and mpi separately
+ // used only in gmres_solver2
+ template
+ inline void axpy (vector_t &x, const vector_t &y, typename vector_t::value_type t)
+ {
+ BS_ASSERT (x.size () == y.size ());
+ BS_ASSERT (x.size ());
+
+ size_t i = 0, cnt = x.size ();
+ const size_t unroll_factor = 8;
+ size_t cnt2 = cnt - (cnt % unroll_factor);
+
+ #ifdef GMRES_SOLVER2_SOLVE_PARALLEL
+ #pragma omp parallel for
+ #endif
+ for (i = 0; i < cnt2; i += unroll_factor)
+ {
+ x[i] += t * y[i];
+ x[i + 1] += t * y[i + 1];
+ x[i + 2] += t * y[i + 2];
+ x[i + 3] += t * y[i + 3];
+ x[i + 4] += t * y[i + 4];
+ x[i + 5] += t * y[i + 5];
+ x[i + 6] += t * y[i + 6];
+ x[i + 7] += t * y[i + 7];
+ }
+ for (; i < cnt; ++i)
+ {
+ x[i] += t * y[i];
+ }
+ }
+
+ /**
+ * @brief AXPY_AYPX // X = Z + P * (X + T * Y)
+ *
+ * @param X -- vector
+ * @param T -- scale factor
+ * @param Y -- vector
+ * @param P -- scale factor
+ * @param Z -- vector
+ * @param I -- index
+ * @param N -- vectors length
+ *
+ * @return nothing
+ */
+ #define AXPY_AYPX(X,T,Y,P,Z,I,N) \
+ for ((I) = 0; (I) < (N); ++(I)) \
+ (X)[(I)] = (Z)[(I)] + (P) * ((X)[(I)] + (T) * (Y)[(I)]);
+
+ template inline void
+ axpy_aypx (vector_t &x, typename vector_t::value_type t, const vector_t &y, typename vector_t::value_type p, const vector_t &z)
+ {
+ BS_ASSERT (x.size ());
+ BS_ASSERT (y.size ());
+ BS_ASSERT (z.size ());
+ BS_ASSERT (x.size () == y.size ());
+ BS_ASSERT (x.size () == z.size ());
+
+ size_t i = 0, cnt = x.size ();
+
+ for (i = 0; i < cnt; ++i)
+ {
+ x[i] = z[i] + p * (x[i] + t * y[i]);
+ }
+ }
+
+ } // end namespace
+
+#endif // #ifndef BS_LIN_SOLV_MACRO_H_
+
diff --git a/bs_base_linear_solvers/include/linear_solvers.h b/bs_base_linear_solvers/include/linear_solvers.h
new file mode 100644
index 0000000..c355beb
--- /dev/null
+++ b/bs_base_linear_solvers/include/linear_solvers.h
@@ -0,0 +1,443 @@
+#ifndef LIN_SOLVER__H
+#define LIN_SOLVER__H
+/*!
+* \file linear_solvers.h
+* \brief linear solvers declaration
+* \author Borschuk Oleg
+* \date 2006-07-26
+*/
+
+#include BS_FORCE_PLUGIN_IMPORT ()
+#include "bcsr_matrix.h"
+#include "named_pbase_access.h"
+#include "bos_report.h"
+#include BS_STOP_PLUGIN_IMPORT ()
+
+namespace blue_sky
+ {
+
+ /**
+ * \brief properties for linear solvers
+ */
+ class BS_API_PLUGIN linear_solver_prop : public named_pbase
+ {
+ typedef property_base base_t; ///< short name for base class
+
+ public:
+ typedef double fp_type_t; ///< short name for used floating point type
+
+ //-----------------------------------------
+ // METHODS
+ //-----------------------------------------
+ public:
+ //! destructor
+ virtual ~linear_solver_prop ();
+
+ //! set maximum number of iterations
+ int set_max_iters (int n_iters);
+
+ //! set tolerance
+ void set_tolerance (fp_type_t new_tol)
+ {
+ if (new_tol > 10e-16)
+ set_param(FP_TOLERANCE,(fp_type_t)new_tol);
+ }
+
+ //! set tolerance
+ void set_matbal_tolerance (fp_type_t new_tol)
+ {
+ if (new_tol > 10e-16)
+ set_param(FP_MATBAL_TOLERANCE,(fp_type_t)new_tol);
+ }
+
+ //! set number of iters
+ void set_iters (int n_iters)
+ {
+ set_param(I_ITERS,n_iters);
+ }
+
+ //! set successively converged flag
+ void set_success (int success)
+ {
+ set_param(I_SUCCESS,success);
+ }
+
+ //! set final resid
+ void set_final_resid (fp_type_t final_resid)
+ {
+ set_param(FP_FINAL_RESID,(fp_type_t)final_resid);
+ }
+
+ //! set relative factor
+ void set_relative_factor (fp_type_t relative_factor)
+ {
+ set_param(FP_RELATIVE_FACTOR,(fp_type_t)relative_factor);
+ }
+
+ //! return != 0 if method successfully converged
+ int check_convergence () const
+ {
+ return get_int(I_SUCCESS);
+ }
+
+ //! return number of iteration
+ int get_iters () const
+ {
+ return get_int(I_ITERS);
+ }
+
+ //! return relative residual denominator
+ fp_type_t get_relative_factor () const
+ {
+ return get_float(FP_RELATIVE_FACTOR);
+ }
+
+ //! return maximum allowed number of iterations
+ int get_max_iters () const
+ {
+ return get_int(I_MAX_ITERS);
+ }
+
+ //! return tolerance
+ fp_type_t get_tolerance () const
+ {
+ return get_float(FP_TOLERANCE);
+ }
+
+ //! get successively converged flag
+ int get_success () const
+ {
+ return get_int(I_SUCCESS);
+ }
+
+ //! get final resid
+ fp_type_t get_final_resid () const
+ {
+ return get_float(FP_FINAL_RESID);
+ }
+
+ //-----------------------------------------
+ // VARIABLES
+ //-----------------------------------------
+ public:
+ PROP_BASE_IDX_DECL_BEGIN(linear_solver_prop,property_base)
+ FP_RELATIVE_FACTOR, //!< Parameter index: denominator for resid array to get relative residual
+ FP_TOLERANCE, //!< Parameter index: tolerance
+ FP_MATBAL_TOLERANCE,
+ FP_FINAL_RESID, //
+ FP_TOTAL,
+ I_ITERS, //!< Parameter index: number of iteration spend for convergence
+ I_MAX_ITERS, //!< Parameter index: maximum number of iteration
+ I_SUCCESS, //!< Parameter index: != 0 if successively converged
+ I_TOTAL,
+ LS_TOTAL,
+ PROP_BASE_IDX_DECL_END
+
+ public:
+ BLUE_SKY_TYPE_DECL (linear_solver_prop);
+ PBASE_ACCESS_MS(linear_solver_prop)
+
+ public:
+ virtual const std::string &get_params_name (idx_type idx);
+ };
+
+ /**
+ * \brief base interface class for linear solvers
+ */
+ template
+ class BS_API_PLUGIN linear_solver_base : public bs_node
+ {
+ //-----------------------------------------
+ // TYPES
+ //-----------------------------------------
+ public:
+ typedef typename strategy_t::matrix_t matrix_t; ///< short name to matrix type
+ typedef typename strategy_t::item_t item_t; ///< short name to array item type (old array_item_t)
+ typedef typename strategy_t::index_t index_t; ///< short name to matrix's index type
+ typedef typename strategy_t::item_array_t item_array_t; ///< short name to array of items type (old array_t)
+ typedef typename strategy_t::index_array_t index_array_t; ///< short name to array type
+ typedef typename strategy_t::wksp_t wksp_t;
+
+ typedef typename strategy_t::rhs_item_t rhs_item_t; ///< short name for type of rhs
+ typedef typename strategy_t::rhs_item_array_t rhs_item_array_t; ///< short name for rhs array type
+
+ typedef linear_solver_base this_t; ///< typedef to this type
+ typedef linear_solver_base base_t; ///< typedef to this type. in child classes used as a short name of base class
+ typedef smart_ptr sp_this_t; ///< short name to smart pointer to this class
+ typedef smart_ptr sp_prop_t; ///< short name to smart pointer to properties holder class
+
+ typedef smart_ptr sp_matrix_t; ///< short name for smart pointer on matrix
+
+ typedef strategy_t strategy_type;
+
+ //-----------------------------------------
+ // METHODS
+ //-----------------------------------------
+ public:
+ // constructor
+ linear_solver_base (bs_type_ctor_param param, bs_node::sp_node node);
+ // destructor
+ virtual ~linear_solver_base ();
+
+ //! solve, used vectors to array
+ virtual int solve (matrix_t * /*matrix*/, typename strategy_t::rhs_item_array_t & /*rhs*/, typename strategy_t::item_array_t & /*sol*/)
+ {
+ BS_ASSERT (false && "PURE CALL");
+ return 0;
+ }
+
+ //! solve, used vectors to array
+ virtual int solve_prec (matrix_t * /*matrix*/, typename strategy_t::item_array_t & /*rhs*/, typename strategy_t::item_array_t & /*sol*/)
+ {
+ BS_ASSERT (false && "PURE CALL");
+ return 0;
+ }
+
+ //! setup
+ virtual int setup (matrix_t * /*matrix*/)
+ {
+ BS_ASSERT (false && "PURE CALL");
+ return 0;
+ }
+
+ //! set preconditioner
+ void set_prec (const this_t *new_prec)
+ {
+ prec = new_prec;
+ set_subnode_in_tree ("prec", sp_this_t (new_prec));
+ }
+
+ //! set solver's properties
+ void set_prop(const linear_solver_prop *new_prop)
+ {
+ prop = new_prop;
+ set_subnode_in_tree ("prop", sp_prop_t (new_prop));
+ }
+
+ //! get properties
+ sp_prop_t get_prop() const
+ {
+ return prop;
+ }
+
+ protected:
+
+ //! set subnode in tree by name
+ void set_subnode_in_tree (const std::string &name, const sp_obj &obj)
+ {
+ //bs_node::erase (name);
+ //bs_node::insert (obj, name, false);
+ }
+
+ /**
+ * \brief Trait class for control of adding new nodes to solver
+ */
+ struct solver_trait : bs_node::sort_traits
+ {
+ /**
+ * \brief Class for sorting sub nodes of solver node
+ */
+ struct solver_key : bs_node::sort_traits::key_type
+ {
+ virtual bool sort_order (const key_ptr & ) const
+ {
+ return true;
+ }
+ };
+
+ virtual const char * sort_name () const
+ {
+ return "solver trait";
+ };
+
+ virtual key_ptr key_generator (const sp_link& /*l*/) const
+ {
+ return new solver_key ();
+ }
+
+ /**
+ * \brief Check passed parameter on accordance to allowed object types
+ *
+ * \param l Link on new object
+ * \return True if parameter allowed, false in other cases
+ */
+ virtual bool accepts (const sp_link& l)
+ {
+ if (l->name() == "prec")
+ {
+ sp_this_t sp(l->data (), bs_dynamic_cast ());
+ return sp;
+ }
+ else if (l->name() == "prop")
+ {
+ sp_prop_t sp (l->data (), bs_dynamic_cast ());
+ return sp;
+ }
+
+ return false;
+ }
+ };
+
+ private:
+ void init();
+
+ //-----------------------------------------
+ // VARIABLES
+ //-----------------------------------------
+ private:
+
+
+ protected:
+ wksp_t wksp; //!< workspace array
+ sp_this_t prec; //!< pointer to the preconditioner
+ sp_prop_t prop; //!< properties for solvers
+
+ public:
+ BLUE_SKY_TYPE_DECL (linear_solver_base);
+ };
+
+ /**
+ * @brief GMRES linear solver
+ */
+ template
+ class BS_API_PLUGIN gmres_solver2 : public linear_solver_base
+ {
+ //-----------------------------------------
+ // TYPES
+ //-----------------------------------------
+ public:
+ typedef typename strategy_t::matrix_t matrix_t; ///< short name to matrix type
+ typedef typename strategy_t::item_array_t item_array_t; ///< short name to array type
+ typedef typename strategy_t::item_t item_t; ///< short name to array item type
+ typedef typename strategy_t::index_t index_t; ///< short name to matrix's index type
+ typedef typename strategy_t::index_array_t index_array_t;
+ typedef typename strategy_t::barrier_t barrier_t;
+
+ typedef typename strategy_t::rhs_item_t rhs_item_t; ///< short name for type of rhs
+ typedef typename strategy_t::rhs_item_array_t rhs_item_array_t; ///< short name for rhs array type
+
+ typedef bcsr_matrix bcsr_matrix_t; ///< short name for used matrix
+ typedef smart_ptr sp_bcsr_matrix_t; ///< short name for smart_pointer on used matrix
+
+ typedef linear_solver_base this_t; ///< typedef to this type
+ typedef linear_solver_base base_t; ///< typedef to this type. in child classes used as a short name of base class
+ typedef smart_ptr sp_this_t; ///< short name to smart pointer to this class
+ typedef smart_ptr sp_prop_t; ///< short name to smart pointer to properties holder class
+
+ typedef smart_ptr sp_matrix_t; ///< short name to smart pointer on matrix_t
+
+ //-----------------------------------------
+ // METHODS
+ //-----------------------------------------
+ public:
+ //! destructor
+ virtual ~gmres_solver2 ();
+
+ //! solve
+ /*virtual int solve (matrix_t *matrix, typename strategy_t::item_array_t & rhs,
+ typename strategy_t::item_array_t & sol);*/
+
+ virtual int solve (matrix_t *matrix, rhs_item_array_t & rhs,
+ item_array_t & sol);
+
+ virtual int solve_prec (matrix_t *matrix, item_array_t & rhs,
+ item_array_t & sol);
+
+ template
+ int
+ templ_solve (matrix_t *matrix, rhs_t &rhs, item_array_t &sol);
+
+ //! setup
+ virtual int setup (matrix_t *matrix);
+
+ private:
+ //-----------------------------------------
+ // VARIABLES
+ //-----------------------------------------
+ public:
+ int m; //!< number of directions to store
+ std::vector vec_p;
+ item_array_t vec_w;
+ item_array_t vec_r;
+
+ public:
+ BLUE_SKY_TYPE_DECL (gmres_solver2);
+ };
+
+
+ /**
+ * @brief BiCGStab linear solver
+ */
+ template
+ class BS_API_PLUGIN bicgstab_solver : public linear_solver_base
+ {
+
+ //-----------------------------------------
+ // TYPES
+ //-----------------------------------------
+ public:
+ typedef typename strategy_t::matrix_t matrix_t; ///< short name to matrix type
+ typedef typename strategy_t::item_array_t item_array_t; ///< short name to array type
+ typedef typename strategy_t::item_t item_t; ///< short name to array item type
+ typedef typename strategy_t::index_t index_t; ///< short name to matrix's index type
+ typedef typename strategy_t::matrix_array_t matrix_array_t; ///< short name to matrix array type
+
+ typedef typename strategy_t::rhs_item_t rhs_item_t; ///< short name for type of rhs
+ typedef typename strategy_t::rhs_item_array_t rhs_item_array_t; ///< short name for rhs array type
+
+ typedef typename strategy_t::index_array_t index_array_t;
+
+ typedef linear_solver_base this_t; ///< typedef to this type
+ typedef linear_solver_base base_t; ///< typedef to this type. in child classes used as a short name of base class
+ typedef smart_ptr sp_this_t; ///< short name to smart pointer to this class
+ typedef smart_ptr sp_prop_t; ///< short name to smart pointer to properties holder class
+
+ typedef smart_ptr sp_matrix_t; ///< short name to smart pointer on matrix_t
+
+ typedef bcsr_matrix bcsr_matrix_t; ///< short name for used matrix
+ typedef smart_ptr sp_bcsr_matrix_t; ///< short name for smart_pointer on used matrix
+
+
+ //-----------------------------------------
+ // METHODS
+ //-----------------------------------------
+ public:
+ //! destructor
+ virtual ~bicgstab_solver ();
+
+ //! solve
+ //virtual int solve (matrix_t *matrix, item_array_t &rhs, item_array_t &sol);
+ virtual int solve (matrix_t *matrix, rhs_item_array_t & rhs,
+ item_array_t & sol);
+
+ virtual int solve_prec (matrix_t *matrix, item_array_t & rhs,
+ item_array_t & sol);
+
+ template
+ int
+ templ_solve (matrix_t *matrix, rhs_t &rhs, item_array_t &sol);
+
+
+ //! setup
+ virtual int setup (matrix_t *matrix);
+
+ private:
+ //-----------------------------------------
+ // VARIABLES
+ //-----------------------------------------
+ public:
+
+ public:
+ BLUE_SKY_TYPE_DECL (bicgstab_solver);
+ };
+
+ //! register linear_solver_prop into kernel
+ bool
+ linear_solver_prop_register_type (const blue_sky::plugin_descriptor &pd);
+
+ //! register linear_solvers into kernel
+ bool
+ linear_solvers_register_type (const blue_sky::plugin_descriptor &pd);
+
+} // namespace blue_sky
+#endif //__LIN_SOLVER__H
diff --git a/bs_base_linear_solvers/include/lu_decomposition.h b/bs_base_linear_solvers/include/lu_decomposition.h
new file mode 100644
index 0000000..c4714fc
--- /dev/null
+++ b/bs_base_linear_solvers/include/lu_decomposition.h
@@ -0,0 +1,65 @@
+#ifndef __LU_DECOMPOSITION_H__
+#define __LU_DECOMPOSITION_H__
+
+
+/*!
+ \file lu_decomposition.h
+ \author Borschuk Oleg
+ \version 0.1
+ \date 3.10.2004
+ \brief file include declarations of functions to build LU decomposition and to solve matrix
+
+ +---+----------------+ matrix is an array of double where elements stored
+ |***|****************| by strings
+ |***|block_size******| |a(0,0) a(0,1) a(0,2)|
+ +---+----------------+ matrix_size |a(1,0) a(1,1) a(1,2)| =>
+ |**block_string******| |a(2,0) a(2,1) a(2,2)|
+ |********************|
+ |********************| => {a(0,0) a(0,1) a(0,2) a(1,0) a(1,1) a(1,2) ...}
+ +--------------------+
+*/
+
+//! minimum for devision
+#define MIN_DIV 1.0e-24
+
+//! default block size
+#define DEF_BLOCK_SIZE 60
+
+template
+struct BS_API_PLUGIN lu_tools
+ {
+ // build LU decomposition for matrix block
+ static i_type lu_block_decomposition (i_type matrix_size, fp_type *block, i_type block_size = 0);
+
+ // find y in Ly = b
+ static i_type lu_block_find_L_roots (i_type matrix_size, fp_type *block, fp_type *r_side, i_type block_size = 0);
+
+ // find x in Ux = y
+ static i_type lu_block_find_U_roots (i_type matrix_size, fp_type *block, fp_type *r_side, i_type block_size = 0);
+
+ // find U in LU = A using known L
+ static i_type lu_block_find_U (i_type matrix_size, fp_type *block_L, fp_type *block_U, i_type block_size, i_type ncol);
+
+ // find L in LU = A using known U
+ static i_type lu_block_find_L (i_type matrix_size, fp_type *block_L, fp_type *block_U, i_type block_size, i_type nrow);
+
+ // upgrade block
+ static i_type lu_block_upgrade (i_type matrix_size, fp_type *block_A, fp_type *block_L,
+ fp_type *block_U, i_type block_size, i_type nrow, i_type ncol);
+
+ // build lu decomposition using block method on one thread
+ static i_type lu_decomposition (i_type matrix_size, fp_type *matrix, i_type block_size = DEF_BLOCK_SIZE);
+
+ // update right side
+ static i_type lu_upgrade_right_side (i_type matrix_size, fp_type *block, i_type nrow, i_type ncol,
+ fp_type *roots, fp_type *r_side);
+ // find y in Ly = b
+ static i_type lu_find_L_roots (i_type matrix_size, fp_type *matrix, fp_type *r_side,
+ i_type block_size = DEF_BLOCK_SIZE);
+
+ // find x in Ux = y
+ static i_type lu_find_U_roots (i_type matrix_size, fp_type *matrix, fp_type *r_side,
+ i_type block_size = DEF_BLOCK_SIZE);
+ };
+
+#endif //__LU_DECOMPOSITION_H__
diff --git a/bs_base_linear_solvers/include/py_linear_solvers.h b/bs_base_linear_solvers/include/py_linear_solvers.h
new file mode 100644
index 0000000..97655d4
--- /dev/null
+++ b/bs_base_linear_solvers/include/py_linear_solvers.h
@@ -0,0 +1,116 @@
+/**
+ * \file py_linear_solvers.h
+ * \brief Python wrapper for linear solvers
+ * \author Miryanov Sergey
+ * \date 2008-04-04
+ */
+
+#ifndef BS_LINEAR_SOLVERS_PYTHON_H
+#define BS_LINEAR_SOLVERS_PYTHON_H
+
+#include "strategies.h"
+#include "linear_solvers.h"
+#include "cgs.h"
+#include "tfqmr.h"
+
+#include BS_FORCE_PLUGIN_IMPORT ()
+#include "py_bcsr_matrix.h"
+#include "write_time_to_log.h"
+#include "dummy_base.h"
+#include "construct_python_object.h"
+#include "make_me_happy.h"
+#include BS_STOP_PLUGIN_IMPORT ()
+
+#include "export_python_wrapper.h"
+
+#ifdef BSPY_EXPORTING_PLUGIN
+namespace blue_sky {
+namespace python {
+
+ /**
+ * \brief python wrapper for most linear solvers
+ */
+ STRATEGY_CLASS_WRAPPER (linear_solver_base, py_linear_solver)
+ {
+ public:
+ typedef linear_solver_base linear_solver_base_t;
+
+ typedef typename strategy_t::matrix_t matrix_t; ///< short name for matrix type from wrapped type
+ typedef typename strategy_t::item_array_t item_array_t; ///< short name for array type from wrapped type
+ typedef typename strategy_t::index_array_t index_array_t;
+ typedef typename strategy_t::rhs_item_t rhs_item_t; ///< short name for type of rhs
+ typedef typename strategy_t::rhs_item_array_t rhs_item_array_t; ///< short name for rhs array type
+
+ typedef py_matrix_base py_matrix_t;
+
+ typedef smart_ptr sp_linear_solver_base_t;
+ typedef smart_ptr sp_prec_t; ///< short name to smart pointer to this class
+ typedef smart_ptr sp_prop_t; ///< short name to smart pointer to properties holder class
+
+ typedef linear_solver_base_t wrapped_t;
+ typedef py_linear_solver_base base_t;
+
+ public:
+
+ STRATEGY_CLASS_WRAPPER_DECL (py_linear_solver);
+
+ WRAPPER_METHOD_R (setup, int, 1, (matrix_t *));
+ WRAPPER_METHOD_R (solve, int, 3, (matrix_t *, rhs_item_array_t &, item_array_t &));
+ WRAPPER_METHOD_R (solve_prec, int, 3, (matrix_t *, item_array_t &, item_array_t &));
+
+ void
+ init_object (linear_solver_base_t *solver)
+ {
+ solver_ = sp_linear_solver_base_t (solver);
+ }
+
+ private:
+
+ sp_linear_solver_base_t solver_;
+ };
+
+#define WRAP_STD_SOLVER(name_, py_name_) \
+ STRATEGY_CLASS_WRAPPER (name_, py_name_) \
+ { \
+ public: \
+ \
+ typedef typename strategy_t::matrix_t matrix_t; \
+ typedef typename strategy_t::item_array_t item_array_t; \
+ typedef typename strategy_t::rhs_item_array_t rhs_item_array_t; \
+ \
+ typedef name_ wrapped_t; \
+ typedef BOOST_PP_CAT (py_name_, _base) base_t; \
+ \
+ public: \
+ \
+ STRATEGY_CLASS_WRAPPER_DECL (py_name_); \
+ \
+ WRAPPER_METHOD_R (setup, int, 1, (matrix_t *)); \
+ WRAPPER_METHOD_R (solve, int, 3, (matrix_t *, rhs_item_array_t &, item_array_t &)); \
+ WRAPPER_METHOD_R (solve_prec, int, 3, (matrix_t *, item_array_t &, item_array_t &)); \
+ };
+
+ WRAP_STD_SOLVER (gmres_solver2, py_gmres_solver);
+ WRAP_STD_SOLVER (bicgstab_solver, py_bicgstab_solver);
+ WRAP_STD_SOLVER (cgs_solver, py_cgs_solver);
+ WRAP_STD_SOLVER (tfqmr_solver, py_tfqmr_solver);
+
+ PY_EXPORTER (solver_exporter, default_exporter)
+ .def ("solve", &T::solve)
+ .def ("solve_prec", &T::solve_prec)
+ .def ("setup", &T::setup)
+ .def ("set_prec", &T::set_prec)
+ .def ("set_prop", &T::set_prop)
+ PY_EXPORTER_END;
+
+ //! export linear_solver_prop to python
+ void py_export_linear_solver_prop ();
+
+ //! export linear solvers to python
+ void py_export_linear_solvers ();
+
+} // namespace python
+} // namespace blue_sky
+
+#endif // #ifdef BSPY_EXPORTING_PLUGIN
+#endif //#ifndef BS_LINEAR_SOLVERS_PYTHON_H
diff --git a/bs_base_linear_solvers/include/solve_helper.h b/bs_base_linear_solvers/include/solve_helper.h
new file mode 100644
index 0000000..544b930
--- /dev/null
+++ b/bs_base_linear_solvers/include/solve_helper.h
@@ -0,0 +1,30 @@
+/**
+ * \file solve_helper.h
+ * \brief impl of
+ * \author Elmira Salimgareeva
+ * \date 31.03.2009
+ * */
+
+#ifndef BS_SOLVE_HELPER_H_
+#define BS_SOLVE_HELPER_H_
+namespace blue_sky
+{
+
+ template
+ int
+ solve_helper (solver_t *solver, typename solver_t::matrix_t *mx, seq_vector &rhs, typename solver_t::item_array_t &sol)
+ {
+ solver->solve (mx, rhs, sol);
+ return 0;
+ }
+
+ template
+ int
+ solve_helper (solver_t *solver, typename solver_t::matrix_t *mx, seq_vector &rhs, typename solver_t::item_array_t &sol)
+ {
+ solver->solve_prec (mx, rhs, sol);
+ return 0;
+ }
+
+}
+#endif //#ifndef BS_SOLVE_HELPER_H_
diff --git a/bs_base_linear_solvers/include/tfqmr.h b/bs_base_linear_solvers/include/tfqmr.h
new file mode 100644
index 0000000..51094a8
--- /dev/null
+++ b/bs_base_linear_solvers/include/tfqmr.h
@@ -0,0 +1,78 @@
+/**
+ * \file tfqmr.h
+ * \brief TFQMR linear solver
+ * \author Salimgareeva E.M.
+ * \date
+ * */
+#ifndef BS_TFQMR_LINEAR_SOLVER_H_
+#define BS_TFQMR_LINEAR_SOLVER_H_
+
+#include "linear_solvers.h"
+
+namespace blue_sky
+ {
+ /**
+ * @brief TFQMR linear solver
+ */
+ template
+ class BS_API_PLUGIN tfqmr_solver : public linear_solver_base
+ {
+
+ //-----------------------------------------
+ // TYPES
+ //-----------------------------------------
+ public:
+ typedef typename strategy_t::matrix_t matrix_t; ///< short name to matrix type
+ typedef typename strategy_t::item_array_t item_array_t; ///< short name to array type
+ typedef typename strategy_t::item_t item_t; ///< short name to array item type
+ typedef typename strategy_t::index_t index_t; ///< short name to matrix's index type
+ typedef typename strategy_t::rhs_item_t rhs_item_t; ///< short name for type of rhs
+ typedef typename strategy_t::rhs_item_array_t rhs_item_array_t; ///< short name for rhs array type
+
+
+ typedef typename strategy_t::matrix_array_t matrix_array_t; ///< short name to matrix array type
+
+ typedef typename strategy_t::index_array_t index_array_t;
+
+ typedef linear_solver_base this_t; ///< typedef to this type
+ typedef linear_solver_base base_t; ///< typedef to this type. in child classes used as a short name of base class
+ typedef smart_ptr sp_this_t; ///< short name to smart pointer to this class
+ typedef smart_ptr sp_prop_t; ///< short name to smart pointer to properties holder class
+
+ typedef smart_ptr sp_matrix_t; ///< short name to smart pointer on matrix_t
+
+ typedef bcsr_matrix bcsr_matrix_t; ///< short name for used matrix
+ typedef smart_ptr sp_bcsr_matrix_t; ///< short name for smart_pointer on used matrix
+
+ //-----------------------------------------
+ // METHODS
+ //-----------------------------------------
+ public:
+ //! destructor
+ virtual ~tfqmr_solver ();
+
+ //! solve
+ virtual int solve (matrix_t *matrix, rhs_item_array_t &rhs, item_array_t &sol);
+
+ virtual int solve_prec (matrix_t *matrix, item_array_t &rhs, item_array_t &sol);
+
+ template
+ int
+ templ_solve (matrix_t *matrix, rhs_t &rhs, item_array_t &sol);
+
+ //! setup
+ virtual int setup (matrix_t *matrix);
+
+ private:
+ //-----------------------------------------
+ // VARIABLES
+ //-----------------------------------------
+ public:
+
+ public:
+ BLUE_SKY_TYPE_DECL (tfqmr_solver);
+ };
+
+ } // namespace blue_sky
+
+#endif // #ifndef BS_TFQMR_LINEAR_SOLVER_H_
diff --git a/bs_base_linear_solvers/src/bs_base_linear_solvers.cpp b/bs_base_linear_solvers/src/bs_base_linear_solvers.cpp
new file mode 100644
index 0000000..4209046
--- /dev/null
+++ b/bs_base_linear_solvers/src/bs_base_linear_solvers.cpp
@@ -0,0 +1,33 @@
+// bs_base_linear_solvers.cpp : Defines the entry point for the DLL application.
+//
+
+#include "bs_base_linear_solvers_stdafx.h"
+
+#include "linear_solvers.h"
+#include "py_linear_solvers.h"
+
+namespace blue_sky {
+ BLUE_SKY_PLUGIN_DESCRIPTOR_EXT ("bs_base_linear_solvers", "1.0.0", "BS_BASE_LINEAR_SOLVERS", "BS_BASE_LINEAR_SOLVERS", "bs_base_linear_solvers")
+
+ BLUE_SKY_REGISTER_PLUGIN_FUN
+ {
+ const plugin_descriptor &pd = *bs_init.pd_;
+
+ bool res = true;
+
+ res &= blue_sky::linear_solver_prop_register_type (pd); BS_ASSERT (res);
+ res &= blue_sky::linear_solvers_register_type (pd); BS_ASSERT (res);
+
+ return res;
+ }
+}
+
+#ifdef BSPY_EXPORTING_PLUGIN
+BLUE_SKY_INIT_PY_FUN
+{
+ using namespace blue_sky::python;
+
+ py_export_linear_solver_prop ();
+ py_export_linear_solvers ();
+}
+#endif
diff --git a/bs_base_linear_solvers/src/cgs.cpp b/bs_base_linear_solvers/src/cgs.cpp
new file mode 100644
index 0000000..f7fbcfc
--- /dev/null
+++ b/bs_base_linear_solvers/src/cgs.cpp
@@ -0,0 +1,315 @@
+/**
+ * \file cgs.cpp
+ * \brief CGS linear solver impl
+ * \author Salimgareeva E.M. (algorithm from "A fast Lanczos-type solver for nonsymmetric linear systems", P.Sonneveld)
+ * \date 11.02.2009
+ * */
+#include "bs_base_linear_solvers_stdafx.h"
+#include "linear_solvers.h"
+#include "cgs.h"
+#include "lin_solv_macro.h"
+
+#include BS_FORCE_PLUGIN_IMPORT ()
+#include "save_seq_vector.h"
+#include BS_STOP_PLUGIN_IMPORT ()
+
+namespace blue_sky
+ {
+
+ //////////////////////////////////////////////////////////////////////////
+ // cgs_solver
+
+ //! constructor
+ template
+ cgs_solver::cgs_solver (bs_type_ctor_param param)
+ : linear_solver_base (param)
+ {}
+
+ //! copy constructor
+ template
+ cgs_solver::cgs_solver(const cgs_solver &solver)
+ : bs_refcounter (), linear_solver_base (solver)
+ {
+ if (&solver != this)
+ *this = solver;
+ }
+
+ //! destructor
+ template
+ cgs_solver::~cgs_solver ()
+ {}
+
+
+ template
+ int cgs_solver::solve(matrix_t *matrix, rhs_item_array_t &rhs, item_array_t &solution)
+ {
+ return templ_solve (matrix, rhs, solution);
+ }
+
+ template
+ int cgs_solver::solve_prec(matrix_t *matrix, item_array_t &rhs, item_array_t &solution)
+ {
+ return templ_solve (matrix, rhs, solution);
+ }
+
+
+ /*!
+ * \brief CGS linear solver
+ *
+ * \param[in] matrix -- pointer to the matrix
+ * \param[in] rhs -- right hand side
+ * \param[out] solution -- solution
+ *
+ * \return 0 if success
+ */
+
+ //template
+ //int cgs_solver::solve(matrix_t *matrix, rhs_item_array_t &rhs, item_array_t &solution)
+ template template int
+ cgs_solver::templ_solve (matrix_t *matrix, rhs_t &rhs, item_array_t &solution)
+ {
+#ifdef _DEBUG
+ BOSOUT (section::solvers, level::debug) << "CGS\n" << bs_end;
+#endif
+ typedef item_t fp_type;
+
+ BS_ERROR (rhs.size (), "cgs_solve");
+ BS_ERROR (solution.size (), "cgs_solve");
+ BS_ERROR (base_t::prop, "cgs_solve");
+
+ const smart_ptr &lprop(this->prop);
+
+ fp_type rho_1, rho_2 = 1, alpha = 1, beta, sigma;
+ int iter;
+ const double epsmac = 1e-24;
+ fp_type r_norm, b_norm, den_norm;
+ //fp_type *x = solution;
+
+ //OMP_TIME_MEASURE_START (cgs_solve_timer);
+
+ item_t tol = this->prop->get_tolerance ();
+ tol *= tol;
+ //resid = prop->get_residuals ();
+ //convergence_rate = prop->get_convergence_rate ();
+
+ index_t max_iter = this->prop->get_max_iters ();
+ index_t n = matrix->n_rows * matrix->n_block_size;
+
+ item_array_t p (n);
+ item_array_t phat (n);
+ item_array_t v (n);
+ item_array_t tmp (n);
+ item_array_t q (n);
+ item_array_t u (n);
+ item_array_t d (n);
+ item_array_t dhat (n);
+ item_array_t r (n);
+ item_array_t rtilde (n);
+ item_array_t r_old (n);
+
+ lprop->set_success (0);
+
+ // solution = {0}
+ assign (solution, n, 0);
+
+ // r = {0}
+ assign (r, n, 0);
+ // TODO:paste
+ assign (tmp, n, 0);
+ assign (p, n, 0);
+ assign (v, n, 0);
+ assign (q, n, 0);
+
+ // p0 = u0 = r0;
+ //memcpy (p, r, n * sizeof (double));
+ u.assign (r.begin (), r.end ());
+ // TODO:end
+
+ // r = Ax0 - b
+ matrix->calc_lin_comb (-1.0, 1.0, solution, rhs, r);
+ rtilde.assign (r.begin (), r.end ());
+
+ //tools::save_seq_vector (tools::string_formater ("1_well_bhp.%s.txt", it->first).str).save (it->second);
+
+ r_norm = bos_helper::mv_vector_inner_product (r, r);
+
+ if (r_norm <= tol) // initial guess quite good
+ return 0;
+
+ rho_1 = r_norm;
+ b_norm = sqrt (bos_helper::mv_vector_inner_product (rhs, rhs));
+
+ // TODO:delete
+ //p.assign (r.begin (), r.end ());
+ //rtilde.assign (r.begin (), r.end ());
+ //v.assign (n, 0);
+ // TODO:end
+
+ if (b_norm > epsmac) // choose convergence criterion
+ {
+ // |r_i|/|b| <= eps if |b| > 0
+ tol *= b_norm;
+ den_norm = b_norm;
+ }
+ else // (r_norm > epsmac)
+ {
+ // |r_i|/|r0| <= eps if |b| = 0
+ tol *= r_norm;
+ den_norm = r_norm;
+ }
+
+ // set up initial norm and convergense factor
+ lprop->set_relative_factor (den_norm);
+
+ // main loop
+ for (iter = 0; iter < max_iter; ++iter)
+ {
+ //printf ("CGS iteration: %d, resid = %le\n", iter, r_norm);
+ //fflush (stdout);
+ // TODO: paste
+ if (iter)
+ {
+ //rho_1 = (r,rtilde)
+ rho_1 = bos_helper::mv_vector_inner_product (r, rtilde); //in first iter equals to r_norm
+ if (rho_1 == 0) // failure
+ {
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+ bs_throw_exception ("CGS: Failure - rho_1 == 0");
+ }
+ }
+
+ beta = rho_1/rho_2; // beta = rho_n/rho_n-1
+ rho_2 = rho_1;
+
+ // u = r + beta*q
+ sum_vector(r, 1., q, beta, u);
+ // tmp = q+beta*p_old
+ sum_vector(q, 1., p, beta, tmp);
+ // p_new = u + beta*tmp
+ sum_vector(u, 1., tmp, beta, p);
+
+ //temp_p.assign (p.begin (), p.end ());
+ if (this->prec)
+ {
+ if (base_t::prec->solve_prec (matrix, p, phat))
+ {
+ bs_throw_exception ("CGS: Preconditioner failed");
+ }
+ }
+ else // no precondition (preconditioner=identity_matrix)
+ {
+ phat.assign (p.begin (), p.end ());
+ }
+
+ // v = A * phat = A * p, if no precondition;
+ assign (v, n, 0);
+
+ matrix->matrix_vector_product (phat, v);
+ // sigma = (v,rtilde)
+ sigma = bos_helper::mv_vector_inner_product (rtilde, v);
+
+ if (sigma > epsmac || sigma < -epsmac)
+ // alpha = rho_1/sigma
+ alpha = rho_1/sigma;
+ else // failure
+ {
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+ bs_throw_exception ("CGS: Failure - sigma == 0");
+ }
+
+ // q = u - alpha*v
+ sum_vector(u, 1., v, -alpha, q);
+ // d = u + q
+ sum_vector(u, 1., q, 1., d);
+
+ // dhat = M^(-1) * d;
+ //temp_d.assign (d.begin (), d.end ());
+ if (this->prec)
+ {
+ if(base_t::prec->solve_prec (matrix, d, dhat))
+ {
+ bs_throw_exception ("CGS: Preconditioner failed");
+ }
+ }
+ else // no precondition (preconditioner=identity_matrix)
+ {
+ dhat.assign (d.begin (), d.end ());
+ }
+
+ assign (tmp, n, 0);
+ // tmp = A*d
+ matrix->matrix_vector_product (dhat, tmp);
+
+ // r = r - alpha*tmp
+ sum_vector(r, 1., tmp, -alpha, r);
+ // x = x + alpha*dhat
+ sum_vector(solution, 1., dhat, alpha, solution);
+
+ r_norm = bos_helper::mv_vector_inner_product (r, r, n);
+
+
+ if (r_norm <= tol) // && check_resid_for_matbalance (n_rows, nb, r, matb_tol))
+ break;
+ }
+
+ //tools::save_seq_vector ("solution.txt").save(solution);
+
+ //TODO: end
+ lprop->set_iters (iter + 1);
+ lprop->set_success (1);
+
+ /*
+ //additional checking convergence
+ mv_calc_lin_comb (matrix, -1.0, 1.0, solution, rhs, r);
+ r_norm = mv_vector_inner_product (r, r, n);
+ */
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+ //printf ("CGS OK! iters = %d, resid = %le\n", lprop->iters, lprop->final_resid);
+ //OMP_TIME_MEASURE_END (bicgstab_solve_timer);
+
+ return 0;
+ }
+
+ /**
+ * @brief setup for CGS
+ *
+ * @param matrix -- input matrix
+ *
+ * @return 0 if success
+ */
+ template int
+ cgs_solver::setup (matrix_t *matrix)
+ {
+ if (!matrix)
+ {
+ bs_throw_exception ("CGS: Passed matrix is null");
+ }
+
+ BS_ASSERT (base_t::prop);
+ if (base_t::prec)
+ {
+ return base_t::prec->setup (matrix);
+ }
+
+ return 0;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ BLUE_SKY_TYPE_STD_CREATE_T_DEF(cgs_solver, (class));
+ BLUE_SKY_TYPE_STD_COPY_T_DEF(cgs_solver, (class));
+
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (cgs_solver) , 1, (linear_solver_base), "cgs_solver_base_fi", "CGS linear solver", "CGS linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (cgs_solver) , 1, (linear_solver_base), "cgs_solver_base_di", "CGS linear solver", "CGS linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (cgs_solver) , 1, (linear_solver_base), "cgs_solver_base_mixi", "CGS linear solver", "CGS linear solver", false);
+ }
diff --git a/bs_base_linear_solvers/src/linear_solvers.cpp b/bs_base_linear_solvers/src/linear_solvers.cpp
new file mode 100644
index 0000000..ad086f0
--- /dev/null
+++ b/bs_base_linear_solvers/src/linear_solvers.cpp
@@ -0,0 +1,944 @@
+/*!
+* \file linear_solvers.cpp
+* \brief implementation of linear solvers
+* \author Borschuk Oleg
+* \date 2006-07-26
+*/
+#include "bs_base_linear_solvers_stdafx.h"
+
+#include "linear_solvers.h"
+#include "lin_solv_macro.h"
+
+#include BS_FORCE_PLUGIN_IMPORT ()
+#include "dummy_base.h"
+#include "bos_report.h"
+#include "vector_assign.h"
+
+#ifdef _MPI
+#include "mpi_csr_matrix.h"
+#include "mpi_vector.h"
+#endif // #ifdef _MPI
+#include BS_STOP_PLUGIN_IMPORT ()
+
+
+
+namespace blue_sky
+{
+namespace bos_helper
+{
+namespace helper
+{
+namespace tmp_ns
+{
+ template struct is_int
+ {
+ enum { value = 0};
+ };
+ template <> struct is_int
+ {
+ enum { value = 1};
+ };
+ template <> struct is_int
+ {
+ enum { value = 1};
+ };
+ template <> struct is_int
+ {
+ enum { value = 1};
+ };
+ template <> struct is_int
+ {
+ enum { value = 1};
+ };
+
+template inline typename vector_v1_t::value_type
+ mv_vector_inner_product (const vector_v1_t &v1, const vector_v2_t &v2, int /* obsolete */ = 0)
+ {
+ BOOST_STATIC_ASSERT (helper::is_int ::value == 0);
+ BOOST_STATIC_ASSERT (helper::is_int ::value == 0);
+
+ typename vector_v1_t::value_type sum = 0;
+ size_t i = 0;
+ size_t n = v1.size ();
+
+ BS_ASSERT (v1.size () == v2.size ());
+
+#ifdef MV_VECTOR_INNER_PRODUCT_PARALLEL
+#pragma omp parallel for reduction (+: sum)
+#endif //MV_VECTOR_INNER_PRODUCT_PARALLEL
+ for (i = 0; i < n; ++i)
+ {
+ sum += v1[i] * v2[i];
+ }
+
+ return sum;
+ }
+}
+}
+}
+}
+
+namespace blue_sky
+ {
+ //namespace tmp_ns
+ //{
+
+ //////////////////////////////////////////////////////////////////////////
+ // linear_solver_prop
+
+ //! constructor
+ linear_solver_prop::linear_solver_prop (bs_type_ctor_param /*param*/)
+ {
+ this->params_names.resize(LS_TOTAL);
+ EREG(linear_solver_prop,FP_RELATIVE_FACTOR,"relative factor");
+ EREG(linear_solver_prop,FP_TOLERANCE,"tolerance");
+ EREG(linear_solver_prop,FP_MATBAL_TOLERANCE,"matbal tolerance");
+ EREG(linear_solver_prop,FP_FINAL_RESID,"final resid");
+
+ EREG(linear_solver_prop,I_ITERS,"iterations count");
+ EREG(linear_solver_prop,I_MAX_ITERS,"max iterations count");
+ EREG(linear_solver_prop,I_SUCCESS,"success");
+
+ resize (LS_TOTAL);
+
+ set_max_iters (30);
+ set_tolerance (1.0e-5);
+ set_relative_factor (1.0);
+ set_success (0);
+ set_iters (0);
+ set_final_resid (0);
+
+
+ }
+
+ //! copy constructor
+ linear_solver_prop::linear_solver_prop (const linear_solver_prop &prop)
+ : bs_refcounter (), named_pbase ()
+ {
+ if (&prop != this)
+ *this = prop;
+ }
+
+ //! destructor
+ linear_solver_prop::~linear_solver_prop ()
+ {
+ }
+
+
+ /**
+ * @brief set maximum number of iterations
+ *
+ * @param n_iters -- number of iterations
+ *
+ * @return 0 if success
+ */
+ int
+ linear_solver_prop::set_max_iters (int n_iters)
+ {
+ int r_code = 0;
+
+ if (n_iters < 0)
+ n_iters = 1;
+
+ //FI_DOUBLE_ARRAY_REALLOCATOR (resid, n_iters + 2, r_code);
+ //FI_DOUBLE_ARRAY_REALLOCATOR (convergence_rate, n_iters + 2, r_code);
+
+ set_param(I_MAX_ITERS,n_iters);
+ return r_code;
+ }
+
+ /**
+ * @brief get parameter name
+ *
+ * @param idx - parameter name
+ *
+ * @return parameter name
+ */
+ const std::string & linear_solver_prop::get_params_name (idx_type idx)
+ {
+ return params_names[idx].name;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // linear_solver_base
+
+ //! constructor
+ template
+ linear_solver_base::linear_solver_base (bs_type_ctor_param /*param*/, bs_node::sp_node node)
+ :bs_node (node)
+ {
+ init();
+ }
+
+ template
+ linear_solver_base::linear_solver_base (bs_type_ctor_param)
+ : bs_node(bs_node::create_node (new solver_trait ()))
+ {
+ init();
+ }
+
+ template
+ void linear_solver_base::init()
+ {
+ prop = BS_KERNEL.create_object (linear_solver_prop::bs_type ());
+ BS_ASSERT (prop);
+
+ //sp_link prec_link = bs_link::create (bs_node::create_node (), "prec");
+ //sp_link prop_link = bs_link::create (bs_node::create_node (), "prop");
+
+ //bs_node::insert (prec_link, false);
+ //bs_node::insert (prop_link, false);
+ }
+
+ template
+ linear_solver_base::linear_solver_base (const linear_solver_base &solver)
+ : bs_refcounter (), bs_node ()
+ {
+ if (&solver != this)
+ *this = solver;
+ }
+
+ //! destructor
+ template
+ linear_solver_base::~linear_solver_base ()
+ {
+ //prec = 0;
+ //prop = 0;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // gmres2_solver
+
+ //! constructor
+ template
+ gmres_solver2::gmres_solver2 (bs_type_ctor_param param)
+ : linear_solver_base (param)
+ {
+ m = 30;
+ }
+
+ //! copy constructor
+ template
+ gmres_solver2::gmres_solver2(const gmres_solver2 &solver)
+ : bs_refcounter (), linear_solver_base (solver)
+ {
+ if (&solver != this)
+ *this = solver;
+ }
+
+ //! destructor
+ template
+ gmres_solver2::~gmres_solver2 ()
+ {
+ m = 30;
+ }
+
+
+ template
+ int gmres_solver2::solve(matrix_t *matrix, rhs_item_array_t &rhs, item_array_t &solution)
+ {
+ return templ_solve (matrix, rhs, solution);
+ }
+
+ template
+ int gmres_solver2::solve_prec(matrix_t *matrix, item_array_t &rhs, item_array_t &solution)
+ {
+ return templ_solve (matrix, rhs, solution);
+ }
+
+
+ /**
+ * @brief restarted GMRES linear solver
+ *
+ * @param matrix -- matrix
+ * @param rhs -- right hand side
+ * @param solution -- solution
+ *
+ * @return 0 if success
+ */
+ template template int
+ gmres_solver2::templ_solve (matrix_t *matrix, rhs_t &rhs, item_array_t &solution)
+ {
+ //tools::save_seq_vector ("rhs_new").save (rhs);
+ typedef typename strat_t::item_t fp_type;
+
+ BS_ASSERT (matrix);
+ BS_ASSERT (rhs.size ());
+ BS_ASSERT (solution.size ());
+ BS_ASSERT (rhs.size () == solution.size ()) (rhs.size ()) (solution.size ());
+ BS_ASSERT (base_t::prop);
+
+ const smart_ptr &lprop (base_t::prop);
+
+ fp_type *rs, *hh, *c, *s;
+ fp_type gamma, t, r_norm, b_norm, den_norm;
+ fp_type *cur_h;
+ const double epsmac = 1.e-16;
+
+ // do barrier at mpi or nothing do at seq (base)
+ // in future we can hold instance of barrier_t as a data member
+ barrier_t ().barrier (barrier_t::comm_world_v ());
+
+ index_t n = matrix->n_rows * matrix->n_block_size;
+ item_t tol = lprop->get_tolerance ();
+
+ // check workspace
+ assign (base_t::wksp, n * (m + 3) + (m + 2) * (m + 1) + 2 * m, 0);
+
+ vec_p.assign (m + 1, item_array_t ());
+ for (int i = 0, cnt = (int)vec_p.size (); i < cnt; ++i)
+ {
+ vec_p[i] = item_array_t ();
+ vec_p[i].template init_by_matrix (matrix);
+ }
+
+ vec_w.template init_by_matrix (matrix);
+ vec_r.template init_by_matrix (matrix);
+
+ // initialize work arrays
+ s = &base_t::wksp[0];
+ c = s + m;
+ rs = c + m;
+ hh = rs + m + 1;
+
+ lprop->set_success (0);
+
+ assign (solution, n, 0);
+
+ //calculate_init_r (n, matrix, solution, rhs, p);
+ matrix->calc_lin_comb (-1.0, 1.0, solution, rhs, vec_p[0]);
+
+ b_norm = sqrt (bos_helper::helper::tmp_ns::mv_vector_inner_product (rhs, rhs));
+ //BOSOUT (section::solvers, level::low) << "b_norm = " << b_norm << bs_end;
+
+
+ /* Since it is does not diminish performance, attempt to return an error flag
+ and notify users when they supply bad input. */
+
+ r_norm = sqrt (bos_helper::helper::tmp_ns::mv_vector_inner_product (vec_p[0], vec_p[0]));
+
+ //BOSOUT (section::solvers, level::low) << "r_norm = " << r_norm << bs_end;
+
+ //printf ("Initial_residual %le\n", r_norm / b_norm);
+
+ if (b_norm > epsmac)
+ {
+ /* convergence criterion |r_i|/|b| <= accuracy if |b| > 0 */
+ tol *= b_norm;
+ den_norm = b_norm;
+ }
+ else
+ {
+ /* convergence criterion |r_i|/|r0| <= accuracy if |b| = 0 */
+ tol *= r_norm;
+ den_norm = r_norm;
+ }
+ // set up initial norm and convergense factor
+ lprop->set_relative_factor (den_norm);
+
+ index_t iter = 0;
+ index_t max_iter = lprop->get_max_iters ();
+ for (iter = 0; iter < max_iter;)
+ {
+ /* initialize first term of hessenberg system */
+ rs[0] = r_norm;
+
+ if (r_norm < epsmac || r_norm <= tol)
+ break;
+
+ t = 1.0 / r_norm;
+
+ scale_vector (vec_p[0], t);
+
+ index_t i = 0;
+ for (i = 1; i < m && iter < max_iter; ++i, ++iter)
+ {
+ barrier_t ().barrier (barrier_t::comm_world_v ());
+
+ //memset (r, 0, sizeof (double) * n);
+ if (this->prec)
+ {
+ if (this->prec->solve_prec (matrix, vec_p[i - 1], vec_r))
+ {
+ bs_throw_exception ("GMRES: Preconditioner failed");
+ }
+ }
+ else // no precondition (preconditioner=identity_matrix)
+ {
+ vec_r.assign (vec_p[i - 1].begin (), vec_p[i - 1].end ());
+ }
+
+ barrier_t ().barrier (barrier_t::comm_world_v ());
+
+ assign (vec_p[i], n, 0);
+ matrix->matrix_vector_product (vec_r, vec_p[i]);
+
+ /* modified Gram_Schmidt */
+ cur_h = hh + (i - 1) * (m + 1);
+ for (index_t j = 0; j < i; ++j)
+ {
+ cur_h[j] = bos_helper::helper::tmp_ns::mv_vector_inner_product (vec_p[j], vec_p[i], n);
+ t = -cur_h[j];
+
+ axpy (vec_p[i], vec_p[j], t);
+ }
+ t = sqrt (bos_helper::helper::tmp_ns::mv_vector_inner_product (vec_p[i], vec_p[i], n));
+ cur_h[i] = t;
+ if (t > epsmac)
+ {
+ t = 1.0 / t;
+
+ scale_vector (vec_p[i], t);
+
+ }
+ /* done with modified Gram_schmidt and Arnoldi step.
+ update factorization of hh */
+ for (index_t j = 1; j < i; j++)
+ {
+ t = cur_h[j - 1];
+ cur_h[j - 1] = c[j - 1] * t + s[j - 1] * cur_h[j];
+ cur_h[j] = -s[j - 1] * t + c[j - 1] * cur_h[j];
+ }
+
+ gamma = sqrt (cur_h[i - 1] * cur_h[i - 1] + cur_h[i] * cur_h[i]);
+
+ if (gamma = 0; --k)
+ {
+ t = rs[k];
+ for (index_t j = k + 1; j < i; j++)
+ {
+ t -= hh[k + j * (m + 1)] * rs[j];
+ }
+ rs[k] = t / hh[k + k * (m + 1)];
+ }
+
+ /* form linear combination of p's to get solution */
+ //vec_w.assign (vec_p[0].begin (), vec_p[0].end ());
+ memcpy (&vec_w[0], &vec_p[0][0], sizeof (item_t) * n);
+ t = rs[0];
+
+ scale_vector (vec_w, t);
+
+ for (index_t j = 1; j < i; j++)
+ {
+ t = rs[j];
+ axpy (vec_w, vec_p[j], t);
+ }
+
+ //memset (r, 0, sizeof (double) * n);
+
+ barrier_t ().barrier (barrier_t::comm_world_v ());
+
+ if (this->prec)
+ {
+ if (base_t::prec->solve_prec (matrix, vec_w, vec_r))
+ {
+ bs_throw_exception ("GMRES: Preconditioner failed");
+ }
+ }
+ else // no precondition (preconditioner=identity_matrix)
+ {
+ //memcpy (r, w, n * sizeof (fp_type));
+ vec_r.assign (vec_w.begin (), vec_w.end ());
+ }
+
+ barrier_t ().barrier (barrier_t::comm_world_v ());
+
+ axpy (solution, vec_r, 1.0);
+
+ /* check for convergence, evaluate actual residual */
+ if (r_norm <= tol)
+ {
+ //break;
+#if 1
+ //calculate_init_r (n, matrix, solution, rhs, r);
+ matrix->calc_lin_comb (-1.0, 1.0, solution, rhs, vec_r);
+
+ r_norm = sqrt (bos_helper::helper::tmp_ns::mv_vector_inner_product (vec_r, vec_r, n));
+
+ if (r_norm <= tol)
+ break;
+ else
+ {
+ //vec_p[0].assign (vec_r.begin (), vec_r.end ());
+ memcpy (&vec_p[0][0], &vec_r[0], sizeof (item_t) * n);
+ i = 0;
+ ++iter;
+ }
+#endif //0
+ }
+
+ /* compute residual vector and continue loop */
+
+ for (index_t j = i; j > 0; --j)
+ {
+ rs[j - 1] = -s[j - 1] * rs[j];
+ rs[j] = c[j - 1] * rs[j];
+ }
+
+ if (i)
+ {
+ t = rs[0];
+ scale_vector (vec_p[0], t);
+
+ }
+ for (index_t j = 1; j < i + 1; ++j)
+ {
+ t = rs[j];
+ axpy (vec_p[0], vec_p[j], t);
+ }
+ }
+
+ lprop->set_iters (iter + 1);
+ lprop->set_success (1);
+
+ if (den_norm > 1.0e-12)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+#ifdef _DEBUG
+ BOSOUT (section::solvers, level::low) << "r_norm = " << r_norm << " r_norm / den_norm = " << r_norm / den_norm << " iter = " << (iter + 1) << bs_end;
+#endif
+
+ barrier_t ().barrier (barrier_t::comm_world_v ());
+
+ return 0;
+ }
+
+ /**
+ * @brief setup GMRES
+ *
+ * @param matrix -- input matrix
+ *
+ * @return 0 if success
+ */
+ template int
+ gmres_solver2::setup (matrix_t *matrix)
+ {
+ BS_ASSERT (matrix);
+ if (!matrix)
+ {
+ bs_throw_exception ("GMRES: Passed matrix is null");
+ }
+
+ if (base_t::prec)
+ {
+ return base_t::prec->setup (matrix);
+ }
+
+ return 0;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // bicgstab_solver
+
+ //! constructor
+ template
+ bicgstab_solver::bicgstab_solver (bs_type_ctor_param param)
+ : linear_solver_base (param)
+ {}
+
+ //! copy constructor
+ template
+ bicgstab_solver::bicgstab_solver(const bicgstab_solver &solver)
+ : bs_refcounter (), linear_solver_base (solver)
+ {
+ if (&solver != this)
+ *this = solver;
+ }
+
+ //! destructor
+ template
+ bicgstab_solver::~bicgstab_solver ()
+ {}
+
+
+
+ template
+ int bicgstab_solver::solve(matrix_t *matrix, rhs_item_array_t &rhs, item_array_t &solution)
+ {
+ return templ_solve (matrix, rhs, solution);
+ }
+
+ template
+ int bicgstab_solver::solve_prec(matrix_t *matrix, item_array_t &rhs, item_array_t &solution)
+ {
+ return templ_solve (matrix, rhs, solution);
+ }
+
+ /*!
+ * \brief BiCGStab linear solver
+ *
+ * \param[in] matrix -- pointer to the matrix
+ * \param[in] rhs -- right hand side
+ * \param[out] solution -- solution
+ *
+ * \return 0 if success
+ */
+ template template int
+ bicgstab_solver::templ_solve (matrix_t *matrix, rhs_t &rhs, item_array_t &solution)
+ {
+ typedef item_t fp_type;
+
+ BS_ERROR (matrix, "bicgstab_solve");
+ BS_ERROR (rhs.size (), "bicgstab_solve");
+ BS_ERROR (solution.size (), "bicgstab_solve");
+ BS_ERROR (base_t::prop, "bicgstab_solve");
+
+ const smart_ptr &lprop(this->prop);
+
+ fp_type rho_1, rho_2 = 1, alpha = 1, beta, omega = 1;
+ int iter;
+ const double epsmac = 1e-24;
+ fp_type r_norm, b_norm, den_norm, s_norm;
+ //fp_type *x = solution;
+
+ //OMP_TIME_MEASURE_START (bicgstab_solve_timer);
+
+ item_t tol = this->prop->get_tolerance ();
+ tol *= tol;
+ //resid = prop->get_residuals ();
+ //convergence_rate = prop->get_convergence_rate ();
+
+ index_t max_iter = this->prop->get_max_iters ();
+ index_t n = matrix->n_rows * matrix->n_block_size;
+
+ item_array_t p (n);
+ item_array_t phat (n);
+ item_array_t s (n);
+ item_array_t shat (n);
+ item_array_t t (n), v (n), r (n), rtilde (n);
+
+ lprop->set_success (0);
+
+ assign (solution, n, 0);
+ assign (r, n, 0);
+
+ matrix->calc_lin_comb (-1.0, 1.0, solution, rhs, r);
+ r_norm = bos_helper::mv_vector_inner_product (r, r);
+ if (r_norm <= tol) // initial guess quite good
+ return 0;
+
+ rho_1 = r_norm;
+ b_norm = sqrt (bos_helper::mv_vector_inner_product (rhs, rhs));
+
+ p.assign (r.begin (), r.end ());
+ rtilde.assign (r.begin (), r.end ());
+ assign (v, n, 0);
+
+ if (b_norm > epsmac) // choose convergence criterion
+ {
+ // |r_i|/|b| <= eps if |b| > 0
+ tol *= b_norm;
+ den_norm = b_norm;
+ }
+ else // (r_norm > epsmac)
+ {
+ // |r_i|/|r0| <= eps if |b| = 0
+ tol *= r_norm;
+ den_norm = r_norm;
+ }
+
+ // set up initial norm and convergense factor
+ lprop->set_relative_factor (den_norm);
+
+ // main loop
+ for (iter = 0; iter < max_iter; ++iter)
+ {
+ //printf ("BiCGStab iteration: %d, resid = %le\n", iter, r_norm);
+ //fflush (stdout);
+
+ if (iter)
+ {
+ rho_1 = bos_helper::mv_vector_inner_product (r, rtilde); //in first iter equals to r_norm
+ if (rho_1 == 0) // failure
+ {
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+ bs_throw_exception (boost::format ("BICGSTAB: Failure - rho_1 == 0, resid = %le") % lprop->get_final_resid ());
+ }
+ beta = (rho_1 / rho_2) * (alpha / omega);
+ // p = r + beta * (p - omega * v);
+ //AXPY_AYPX (p, -omega, v, beta, r, k, n);
+ axpy_aypx (p, -omega, v, beta, r);
+ }
+
+ // phat = M^(-1) * p;
+ if (this->prec)
+ {
+ if (base_t::prec->solve_prec (matrix, p, phat))
+ {
+ bs_throw_exception ("BICGSTAB: Preconditioner failed");
+ }
+ }
+ else // no precondition (preconditioner=identity_matrix)
+ {
+ phat.assign (p.begin (), p.end ());
+ }
+
+ // v = A * phat;
+ assign (v, n, 0);
+ matrix->matrix_vector_product (phat, v);
+
+ alpha = bos_helper::mv_vector_inner_product (rtilde, v);
+ if (alpha > epsmac || alpha < -epsmac)
+ alpha = rho_1 / alpha;
+ else // failure
+ {
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+ bs_throw_exception (boost::format ("BICGSTAB: Failure - (rtilde, v) == 0, resid = %le") % lprop->get_final_resid ());
+ }
+
+ // s = r - alpha * v;
+ s.assign (r.begin (), r.end ());
+ axpy (s, v, -alpha);
+ //AXPY (s, -alpha, v, k, n);
+
+ //x = x + alpha * phat;
+ //AXPY (x, alpha, phat, k, n);
+ //axpy (x, phat, alpha);
+ axpy (solution, phat, alpha);
+
+ s_norm = bos_helper::mv_vector_inner_product (s, s);
+ if (s_norm < tol)
+ {
+ //check convergence
+ //matrix->calc_lin_comb (-1.0, 1.0, x, rhs, t);// t is buffer
+ matrix->calc_lin_comb (-1.0, 1.0, solution, rhs, t);// t is buffer
+ r_norm = bos_helper::mv_vector_inner_product (t, t);
+ if (r_norm <= tol)
+ break;
+ }
+
+ // shat = M^(-1) * s;
+ if (this->prec)
+ {
+ if (base_t::prec->solve_prec (matrix, s, shat))
+ {
+ bs_throw_exception ("BICGSTAB: Preconditioner failed");
+ }
+ }
+ else // no precondition (preconditioner=identity_matrix)
+ {
+ shat.assign (s.begin (), s.end ());
+ }
+
+ // t = A * shat;
+ assign (t, n, 0);
+ matrix->matrix_vector_product (shat, t);
+
+ // omega = (t,s) / (t,t);
+ omega = bos_helper::mv_vector_inner_product (t, t);
+ if (omega > epsmac)
+ {
+ omega = bos_helper::mv_vector_inner_product (t, s) / omega;
+ }
+ else // failure
+ {
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+ bs_throw_exception (boost::format ("BICGSTAB: Failure - (t, t) == 0, resid = %le") % lprop->get_final_resid ());
+ }
+
+ if (omega < epsmac) // failure
+ {
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+ bs_throw_exception (boost::format ("BICGSTAB: Failure - omega == 0, resid = %le") % lprop->get_final_resid ());
+ }
+
+ //x = x + omega * shat;
+ //AXPY (x, omega, shat, k, n);
+ //axpy (x, shat, omega);
+ axpy (solution, shat, omega);
+
+ //r = s - omega * t;
+ //memcpy (r, s, n * sizeof (fp_type));
+ //AXPY (r, -omega, t, k, n);
+ r.assign (s.begin (), s.end ());
+ axpy (r, t, -omega);
+ /*
+ //additional check convergence
+ mv_calc_lin_comb (matrix, -1.0, 1.0, x, rhs, s); // s is buffer
+ r_norm = mv_vector_inner_product (s, s, n);
+ */
+ r_norm = bos_helper::mv_vector_inner_product (r, r);
+ if (r_norm <= tol)
+ break;
+
+ rho_2 = rho_1;
+ } // end of main loop
+
+ lprop->set_iters (iter + 1);
+ lprop->set_success (1);
+
+ //printf ("BiCGStab after iteration: %d, resid = %le\n", iter, r_norm);
+ /*
+ //additional checking convergence
+ mv_calc_lin_comb (matrix, -1.0, 1.0, solution, rhs, r);
+ r_norm = mv_vector_inner_product (r, r, n);
+ */
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+ BOSOUT (section::solvers, level::low) << "r_norm = " << r_norm << " r_norm / den_norm = " << r_norm / den_norm << " iter = " << iter << bs_end;
+
+ // printf ("BiCGStab OK! iters = %d, resid = %le\n", prop->iters, prop->final_resid);
+ //OMP_TIME_MEASURE_END (bicgstab_solve_timer);
+
+ return 0;
+ }
+
+ /**
+ * @brief setup for BiCGStab
+ *
+ * @param matrix -- input matrix
+ *
+ * @return 0 if success
+ */
+ template int
+ bicgstab_solver::setup (matrix_t *matrix)
+ {
+ BS_ASSERT (matrix);
+ if (!matrix)
+ {
+ bs_throw_exception ("BICGSTAB: Passed matrix is null");
+ }
+
+ BS_ASSERT (base_t::prop);
+ if (base_t::prec)
+ {
+ return base_t::prec->setup (matrix);
+ }
+
+ return 0;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ BLUE_SKY_TYPE_STD_CREATE(linear_solver_prop);
+ BLUE_SKY_TYPE_STD_COPY(linear_solver_prop);
+ BLUE_SKY_TYPE_IMPL(linear_solver_prop, objbase, "linear_solver_prop", "Property for linear solvers", "Property for linear solvers");
+
+ //////////////////////////////////////////////////////////////////////////
+ BLUE_SKY_TYPE_STD_CREATE_T_DEF(linear_solver_base, (class));
+ BLUE_SKY_TYPE_STD_COPY_T_DEF(linear_solver_base, (class));
+
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (linear_solver_base) , 1, (objbase), "linear_solver_base_fi", "linear solver", "linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (linear_solver_base) , 1, (objbase), "linear_solver_base_di", "linear solver", "linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (linear_solver_base) , 1, (objbase), "linear_solver_base_mixi", "linear solver", "linear solver", false);
+
+#ifdef _MPI
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (linear_solver_base) , 1, (objbase), "linear_solver_mpi_di", "linear solver", "linear solver", false);
+#endif
+ //////////////////////////////////////////////////////////////////////////
+ BLUE_SKY_TYPE_STD_CREATE_T_DEF(gmres_solver2, (class));
+ BLUE_SKY_TYPE_STD_COPY_T_DEF(gmres_solver2, (class));
+
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (gmres_solver2) , 1, (linear_solver_base), "gmres_solver2_base_fi", "GMRES linear solver", "GMRES linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (gmres_solver2) , 1, (linear_solver_base), "gmres_solver2_base_di", "GMRES linear solver", "GMRES linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (gmres_solver2) , 1, (linear_solver_base), "gmres_solver2_base_mixi", "GMRES linear solver", "GMRES linear solver", false);
+
+#ifdef _MPI
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (gmres_solver2) , 1, (linear_solver_base), "gmres_solver2_mpi_di", "GMRES linear solver", "GMRES linear solver", false);
+#endif
+ //////////////////////////////////////////////////////////////////////////
+ BLUE_SKY_TYPE_STD_CREATE_T_DEF(bicgstab_solver, (class));
+ BLUE_SKY_TYPE_STD_COPY_T_DEF(bicgstab_solver, (class));
+
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (bicgstab_solver) , 1, (linear_solver_base), "bicgstab_solver_base_fi", "BiCG linear solver", "BiCG linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (bicgstab_solver) , 1, (linear_solver_base), "bicgstab_solver_base_di", "BiCG linear solver", "BiCG linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (bicgstab_solver) , 1, (linear_solver_base), "bicgstab_solver_base_mixi", "BiCG linear solver", "BiCG linear solver", false);
+
+ //////////////////////////////////////////////////////////////////////////
+ // register types
+
+ bool
+ linear_solver_prop_register_type (const blue_sky::plugin_descriptor &pd)
+ {
+ bool res = true;
+ res &= BS_KERNEL.register_type (pd, linear_solver_prop::bs_type ());
+
+ return res;
+ }
+ bool
+ linear_solvers_register_type (const blue_sky::plugin_descriptor &pd)
+ {
+ bool res = true;
+
+ res &= BS_KERNEL.register_type (pd, linear_solver_base::bs_type ());
+ BS_ASSERT (res);
+ res &= BS_KERNEL.register_type (pd, linear_solver_base::bs_type ());
+ BS_ASSERT (res);
+ res &= BS_KERNEL.register_type (pd, linear_solver_base::bs_type ());
+ BS_ASSERT (res);
+
+
+ res &= BS_KERNEL.register_type (pd, gmres_solver2::bs_type ());
+ BS_ASSERT (res);
+ res &= BS_KERNEL.register_type (pd, gmres_solver2::bs_type ());
+ BS_ASSERT (res);
+ res &= BS_KERNEL.register_type (pd, gmres_solver2::bs_type ());
+ BS_ASSERT (res);
+
+
+
+#ifdef _MPI
+ res &= BS_KERNEL.register_type (pd, gmres_solver2::bs_type ());
+#endif
+
+ res &= BS_KERNEL.register_type (pd, bicgstab_solver::bs_type ());
+ BS_ASSERT (res);
+ res &= BS_KERNEL.register_type (pd, bicgstab_solver::bs_type ());
+ BS_ASSERT (res);
+ res &= BS_KERNEL.register_type (pd, bicgstab_solver::bs_type ());
+ BS_ASSERT (res);
+
+
+
+ return res;
+ }
+
+// } // namespace tmp_ns
+} // namespace blue_sky
diff --git a/bs_base_linear_solvers/src/lu_decomposition.cpp b/bs_base_linear_solvers/src/lu_decomposition.cpp
new file mode 100644
index 0000000..b083c3e
--- /dev/null
+++ b/bs_base_linear_solvers/src/lu_decomposition.cpp
@@ -0,0 +1,515 @@
+/*!
+ \file lu_decomposition.cpp
+ \author Borschuk Oleg
+ \version 0.1
+ \date 3.10.2004
+ \brief file include functions to build LU decomposition and to solve matrix
+*/
+#include "bs_base_linear_solvers_stdafx.h"
+
+#include
+
+#include "lu_decomposition.h"
+
+#define LU_2x2(m_str_0, m_str_1) \
+ m_str_0[1] /= m_str_0[0]; \
+ m_str_1[1] -= m_str_0[1] * m_str_1[0];
+
+#define LU_3x3(m_str_0, m_str_1, m_str_2) \
+ LU_2x2(m_str_0, m_str_1) \
+ m_str_0[2] /= m_str_0[0]; \
+ m_str_1[2] -= m_str_0[1] * m_str_1[0]; \
+ m_str_1[2] /= m_str_1[1]; \
+ m_str_2[1] -= m_str_0[1] * m_str_2[0]; \
+ m_str_2[2] -= m_str_0[2] * m_str_2[0]; \
+ m_str_2[2] -= m_str_2[1] * m_str_1[2];
+
+
+
+
+/*!
+ \fn int lu_block_decomposition (int matrix_size, double *block, int block_size)
+ \brief build lu decomposition for matrix lock
+ \param matrix_size -- size of matrix
+ \param block -- poiter to the first element of block, if need to decompose full
+ matrix send pointer to the matrix and set block_size to zero,
+ matrix must be stored by strings
+ \param block_size -- size of block
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_block_decomposition (i_type matrix_size, fp_type *block, i_type block_size)
+{
+ using namespace blue_sky;
+
+ BS_ASSERT (block);
+ BS_ASSERT (matrix_size >= 1) (matrix_size);
+ BS_ASSERT (block_size == matrix_size) (block_size) (matrix_size);
+
+ // declaration
+ i_type i, j, k;
+
+ // main loop
+ fp_type *uprow = &block[0];
+ for (k = 0; k < block_size; ++k, uprow += matrix_size)
+ {
+ // check diagonal element
+ if (fabs (uprow[k]) < MIN_DIV)
+ return -2;
+
+ fp_type diag = (fp_type)(1.0 / uprow[k]);
+ for (j = k + 1; j < block_size; ++j)
+ {
+ uprow[j] *= diag;
+ }
+
+ // upgrade other elements
+ fp_type *row = &block[(k + 1) * matrix_size];
+ for (i = k + 1; i < block_size; ++i, row += matrix_size)
+ {
+ fp_type row_k = row[k];
+ for (j = k + 1; j < block_size; ++j)
+ {
+ row[j] -= uprow[j] * row_k;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/*!
+ \fn int lu_block_find_L_roots (int matrix_size, double *block,
+ double *r_side, int block_size = 0)
+ \brief find y in Ly = b
+ \param matrix_size -- size of matrix
+ \param block -- poiter to the first element of block, if need to find roots in full
+ matrix send pointer to the matrix and set block_size to zero,
+ matrix must be stored by strings
+ \param r_side -- pointer to the first element of block in right side array
+ \param block_size -- size of block
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_block_find_L_roots (i_type matrix_size, fp_type *block, fp_type *r_side, i_type block_size)
+{
+ using namespace blue_sky;
+ BS_ASSERT (block);
+ BS_ASSERT (r_side);
+ BS_ASSERT (matrix_size >= 1) (matrix_size);
+ BS_ASSERT (block_size >= 1) (block_size);
+ BS_ASSERT (block_size == matrix_size) (block_size) (matrix_size);
+
+ for (i_type i = 0; i < block_size; ++i)
+ {
+ BS_ASSERT (fabs (block [i * matrix_size + i]) >= MIN_DIV) (i) (matrix_size) (block [i * matrix_size + i]) (MIN_DIV);
+ //if (fabs (block[i * matrix_size + i]) < MIN_DIV)
+ // {
+ // return -2;
+ // }
+
+ r_side[i] /= block[i * matrix_size + i];
+ fp_type r_side_i = r_side[i];
+ fp_type *b = &block[(i + 1) * matrix_size + i];
+ for (i_type j = i + 1; j < block_size; ++j, b += matrix_size)
+ {
+ r_side[j] -= r_side_i * b[0];
+ }
+ }
+ return 0;
+}
+
+/*!
+ \fn int lu_block_find_U_roots (int matrix_size, double *block,
+ double *r_side, int block_size = 0)
+ \brief find x in Lx = y
+ \param matrix_size -- size of matrix
+ \param block -- poiter to the first element of block, if need to find roots in full
+ matrix send pointer to the matrix and set block_size to zero,
+ matrix must be stored by strings
+ \param r_side -- pointer to the first element of block in right side array
+ \param block_size -- size of block
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_block_find_U_roots (i_type matrix_size, fp_type *block, fp_type *r_side, i_type block_size)
+{
+ using namespace blue_sky;
+ BS_ASSERT (block);
+ BS_ASSERT (r_side);
+ BS_ASSERT (matrix_size >= 1) (matrix_size);
+ BS_ASSERT (block_size >= 1) (block_size);
+ BS_ASSERT (block_size == matrix_size) (block_size) (matrix_size);
+
+ for (i_type i = block_size - 1; i >= 0; --i)
+ {
+ fp_type r_side_i = r_side[i];
+ fp_type *b = &block[(i - 1) * matrix_size + i];
+ for (i_type j = i - 1; j >= 0; --j, b -= matrix_size)
+ {
+ r_side[j] -= r_side_i * b[0];
+ }
+ }
+ return 0;
+}
+
+/*!
+ \fn int lu_block_find_U (int matrix_size, double *block_L,
+ double *block_U, int nrow, int ncol)
+ \brief find U in LU = A using known L and A
+ \param matrix_size -- size of matrix
+ \param block_L -- poiter to the first element of block L
+ \param block_U -- pointer to the first element of block A and U
+ \param block_size -- size of block
+ \param ncol -- number of columns in U block
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_block_find_U (i_type matrix_size, fp_type *block_L, fp_type *block_U, i_type block_size, i_type ncol)
+{
+ i_type i, j, k;
+ // check input variables
+ if (matrix_size < 1 || !block_L || !block_U)
+ return -1;
+ for (k = 0; k < ncol; ++k)
+ {
+ for (i = 0; i < block_size; ++i)
+ {
+ //todo: not need to check values every time
+ if (fabs (block_L[i * matrix_size + i]) < MIN_DIV)
+ return -2;
+ block_U[i * matrix_size + k] /= block_L[i * matrix_size + i];
+ for (j = i + 1; j < block_size; ++j)
+ block_U[j * matrix_size + k] -= block_U[i * matrix_size + k]
+ * block_L[j * matrix_size + i];
+ }
+
+ }
+ return 0;
+}
+
+/*!
+ \fn int lu_block_find_L (int matrix_size, double *block_L,
+ double *block_U, int nrow, int ncol)
+ \brief find L in LU = A using known U and A
+ \param matrix_size -- size of matrix
+ \param block_L -- poiter to the first element of block L and A
+ \param block_U -- pointer to the first element of block U
+ \param nrow -- number of rows in L block
+ \param block_size -- size of block
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_block_find_L (i_type matrix_size, fp_type *block_L, fp_type *block_U, i_type block_size, i_type nrow)
+{
+ i_type i, j, k;
+ // check input variables
+ if (matrix_size < 1 || !block_L || !block_U)
+ return -1;
+ for (k = 0; k < nrow; ++k)
+ {
+ for (i = 0; i < block_size; ++i)
+ {
+ for (j = i + 1; j < block_size; ++j)
+ block_L[j + k * matrix_size] -= block_L[i + k * matrix_size]
+ * block_U[j + i * matrix_size];
+ }
+
+ }
+ return 0;
+}
+
+/*!
+ \fn int lu_block_upgrade (int matrix_size, double *block_A, double *block_L,
+ double *block_U, int block_size, int nrow, int ncol)
+ \brief update block_A using given block_L and block_U
+ \param matrix_size -- size of matrix
+ \param block_A -- pointer to the first element of block A
+ \param block_L -- poiter to the first element of block L
+ \param block_U -- pointer to the first element of block U
+ \param block_size -- size of block
+ \param nrow -- number of rows in L block
+ \param ncol -- number of columns in U block
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_block_upgrade (i_type matrix_size, fp_type *block_A, fp_type *block_L,
+ fp_type *block_U, i_type block_size, i_type nrow, i_type ncol)
+{
+ i_type i, j, k;
+ fp_type update_value;
+
+ // check input data
+ if (!block_A || !block_L || !block_U || matrix_size < 1
+ || block_size < 1 || nrow < 1 || ncol < 1)
+ return -1;
+
+ // main loop
+ for (i = 0; i < nrow; ++i)
+ {
+ for (j = 0; j < ncol; ++j)
+ {
+ update_value = 0;
+ for (k = 0; k < block_size; ++k)
+ update_value += block_L[i * matrix_size + k] * block_U[k * matrix_size +j];
+ block_A[i * matrix_size + j] -= update_value;
+ }
+ }
+ return 0;
+}
+
+/*!
+ \fn int lu_decomposition (int matrix_size, double *matrix, int block_size)
+ \brief build lu decomposition using block method on one thread
+ \param matrix_size -- size of matrix
+ \param matrix -- matrix to decompose
+ \param block_size -- size of block (default value is 60)
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_decomposition (i_type matrix_size, fp_type *matrix, i_type block_size)
+{
+ i_type i, j, k;
+ i_type global_i;
+ i_type ret_code;
+ // last block size
+ i_type last_block_size;
+ // number of blocks in matrix string
+ i_type number_of_blocks;
+ // block on the corner
+ fp_type *corner_block = 0;
+ // L block
+ fp_type *block_L = 0;
+ // U block
+ fp_type *block_U = 0;
+ // A block
+ fp_type *block_A = 0;
+
+
+ // check input data
+ if (matrix_size < 1 || !matrix)
+ return -1;
+ if (block_size >= matrix_size || block_size < 2)
+ return lu_block_decomposition (matrix_size, matrix);
+
+ // calculate number of blocks and size of last block
+ number_of_blocks = matrix_size / block_size;
+ last_block_size = matrix_size % block_size;
+ if (last_block_size > 0)
+ ++number_of_blocks;
+ else
+ last_block_size = block_size;
+
+ // main loop
+ for (i = 0; i < number_of_blocks; ++i)
+ {
+ // find LU decomposition for block[i, i]
+ global_i = i * block_size;
+ corner_block = &(matrix[global_i * matrix_size + global_i]);
+ ret_code = lu_block_decomposition (matrix_size,
+ corner_block,
+ ((i + 1) < number_of_blocks ? block_size : last_block_size));
+ if (ret_code) return ret_code;
+
+ // find all U blocks in block string
+ for (k = i + 1; k < number_of_blocks; ++k)
+ {
+ ret_code = lu_block_find_U (matrix_size,
+ corner_block,
+ &(matrix[global_i * matrix_size + k * block_size]),
+ block_size,
+ ((k + 1) < number_of_blocks ? block_size : last_block_size));
+ if (ret_code) return ret_code;
+ }
+ // find all L blocks in block column
+ for (k = i + 1; k < number_of_blocks; ++k)
+ {
+ ret_code = lu_block_find_L (matrix_size,
+ &(matrix[k * block_size * matrix_size + global_i]),
+ corner_block,
+ block_size,
+ ((k + 1) < number_of_blocks ? block_size : last_block_size));
+ if (ret_code) return ret_code;
+ }
+ // update other blocks
+ for (k = i + 1; k < number_of_blocks; ++k)
+ {
+ block_L = &(matrix[k * block_size * matrix_size + global_i]);
+ for (j = i + 1; j < number_of_blocks; ++j)
+ {
+ block_U = &(matrix[global_i * matrix_size + j * block_size]);
+ block_A = &(matrix[k * block_size * matrix_size + j * block_size]);
+ ret_code = lu_block_upgrade (matrix_size, block_A, block_L, block_U, block_size,
+ ((k + 1) < number_of_blocks ? block_size : last_block_size),
+ ((j + 1) < number_of_blocks ? block_size : last_block_size));
+ if (ret_code) return ret_code;
+ }
+ }
+ }
+ return 0;
+}
+
+/*!
+ \fn int lu_upgrade_right_side (int matrix_size, double *block, int nrow, int ncol,
+ double *roots, double *r_side)
+ \brief update right side
+ \param matrix_size -- size of matrix
+ \param block -- pointer to the first element of block
+ \param nrow -- number of rows in upgrade block
+ \param ncol -- number of columns in upgrade block
+ \param roots -- known vector of roots
+ \param r_side -- vector of upgrade roots
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_upgrade_right_side (i_type matrix_size, fp_type *block, i_type nrow, i_type ncol,
+ fp_type *roots, fp_type *r_side)
+{
+ i_type i, j;
+ fp_type upgrade_value = 0;
+ fp_type *block_row = 0;
+
+ // check input data
+ if (matrix_size < 1 || !block || nrow < 1 || ncol < 1 || !roots || !r_side)
+ return -1;
+
+ for (i = 0; i < nrow; ++i)
+ {
+ upgrade_value = 0;
+ block_row = &(block[i * matrix_size]);
+ for (j = 0; j < ncol; ++j)
+ upgrade_value += block_row[j] * roots[j];
+ r_side[i] -= upgrade_value;
+ }
+ return 0;
+}
+
+
+/*!
+ \fn int lu_find_L_roots (int matrix_size, double *matrix, double *r_side,
+ int block_size = DEF_BLOCK_SIZE)
+ \brief find y in Ly = b
+ \param matrix_size -- size of matrix
+ \param matrix -- pointer to the lu matrix
+ \param r_side -- given right side
+ \param block_size -- block size, default value DEF_BLOCK_SIZE
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_find_L_roots (i_type matrix_size, fp_type *matrix, fp_type *r_side, i_type block_size)
+{
+ i_type i;
+ i_type k;
+ i_type ret_code;
+ // last block size
+ i_type last_block_size;
+ // number of blocks in matrix string
+ i_type number_of_blocks;
+
+ // check input data
+ if (matrix_size < 1 || !matrix || !r_side || block_size < 1)
+ return -1;
+
+ // calculate number of blocks and size of last block
+ number_of_blocks = matrix_size / block_size;
+ last_block_size = matrix_size % block_size;
+ if (last_block_size > 0)
+ ++number_of_blocks;
+ else
+ last_block_size = block_size;
+
+ // main loop
+ for (i = 0; i < number_of_blocks; ++i)
+ {//libconfig::ParseException
+ ret_code = lu_block_find_L_roots (matrix_size,
+ &(matrix[i * block_size * (matrix_size + 1)]),
+ &(r_side[i * block_size]),
+ ((i + 1) < number_of_blocks ? block_size : last_block_size));
+ if (ret_code) return ret_code;
+
+ // update all blocks in block column
+ for (k = i + 1; k < number_of_blocks; ++k)
+ {
+ ret_code = lu_upgrade_right_side (matrix_size,
+ &(matrix[(k * matrix_size + i) * block_size]),
+ ((k + 1) < number_of_blocks ? block_size :last_block_size),
+ ((i + 1) < number_of_blocks ? block_size :last_block_size),
+ &(r_side[i * block_size]),
+ &(r_side[k * block_size]));
+ if (ret_code) return ret_code;
+
+ }
+ }
+ return 0;
+}
+
+/*!
+ \fn int lu_find_U_roots (int matrix_size, double *matrix, double *r_side,
+ int block_size = DEF_BLOCK_SIZE)
+ \brief find x in Ux = y
+ \param matrix_size -- size of matrix
+ \param matrix -- pointer to the lu matrix
+ \param r_side -- given right side
+ \param block_size -- block size, default value DEF_BLOCK_SIZE
+ \return 0 if success
+ \return < 0 if error occur
+*/
+template i_type
+lu_tools::lu_find_U_roots (i_type matrix_size, fp_type *matrix, fp_type *r_side, i_type block_size)
+{
+ i_type i;
+ i_type k;
+ i_type ret_code;
+ // last block size
+ i_type last_block_size;
+ // number of blocks in matrix string
+ i_type number_of_blocks;
+
+ // check input datalibconfig::ParseException
+ if (matrix_size < 1 || !matrix || !r_side || block_size < 1)
+ return -1;
+
+ // calculate number of blocks and size of last block
+ number_of_blocks = matrix_size / block_size;
+ last_block_size = matrix_size % block_size;
+ if (last_block_size > 0)
+ ++number_of_blocks;
+ else
+ last_block_size = block_size;
+
+ // main loop
+ for (i = number_of_blocks - 1; i >= 0; --i)
+ {
+ ret_code = lu_block_find_U_roots (matrix_size,
+ &(matrix[i * block_size * (matrix_size + 1)]),
+ &(r_side[i * block_size]),
+ ((i + 1) < number_of_blocks ? block_size : last_block_size));
+ if (ret_code) return ret_code;
+
+ // update all blocks in block column
+ for (k = i - 1; k >= 0; --k)
+ {
+ ret_code = lu_upgrade_right_side (matrix_size,
+ &(matrix[(k * matrix_size + i) * block_size]),
+ ((k + 1) < number_of_blocks ? block_size :last_block_size),
+ ((i + 1) < number_of_blocks ? block_size :last_block_size),
+ &(r_side[i * block_size]),
+ &(r_side[k * block_size]));
+ if (ret_code) return ret_code;
+
+ }
+ }
+ return 0;
+}
+
+template struct lu_tools;
+template struct lu_tools;
diff --git a/bs_base_linear_solvers/src/py_linear_solvers.cpp b/bs_base_linear_solvers/src/py_linear_solvers.cpp
new file mode 100644
index 0000000..c7d2e75
--- /dev/null
+++ b/bs_base_linear_solvers/src/py_linear_solvers.cpp
@@ -0,0 +1,57 @@
+/**
+* \file py_linear_solvers.cpp
+* \brief Python wrapper for linear solvers
+* \author Miryanov Sergey
+* \date 2008-04-04
+*/
+
+#include "bs_base_linear_solvers_stdafx.h"
+#include "py_linear_solvers.h"
+
+using namespace boost::python;
+#ifdef BSPY_EXPORTING_PLUGIN
+
+namespace blue_sky {
+namespace python {
+ //////////////////////////////////////////////////////////////////////////
+ //! export linear_solver_prop to python
+ void py_export_linear_solver_prop ()
+ {
+ class_ , boost::noncopyable>("linear_solver_prop", no_init)
+ .def ("__cons__", make_constructor (construct_python_object ))
+ .def ("__init__", make_function (init_python_object ))
+ .def ("set_max_iters", &linear_solver_prop::set_max_iters)
+ .def ("set_tolerance", &linear_solver_prop::set_tolerance)
+ .def ("check_convergence", &linear_solver_prop::check_convergence)
+ .def ("get_iters", &linear_solver_prop::get_iters)
+ .def ("set_iters", &linear_solver_prop::set_iters)
+ .def ("get_relative_factor", &linear_solver_prop::get_relative_factor)
+ .def ("get_max_iters", &linear_solver_prop::get_max_iters)
+ .def ("get_tolerance", &linear_solver_prop::get_tolerance)
+ .def ("get_final_resid", &linear_solver_prop::get_final_resid)
+ ;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ //! export linear solvers to python
+ void py_export_linear_solvers ()
+ {
+ using namespace boost::python;
+
+ strategy_exporter::export_base ("linear_solver");
+
+ strategy_exporter::export_class ("linear_solver_wrapper");
+ strategy_exporter::export_class ("gmres_solver2_seq");
+ strategy_exporter::export_class ("bicgstab_solver_seq");
+ strategy_exporter::export_class ("cgs_solver_seq");
+ strategy_exporter::export_class ("tfqmr_solver_seq");
+
+#ifdef _MPI
+ solver_export , py_matrix_base , mpi_vector > > > ("gmres_solver2_mpi_di");
+#endif
+ }
+
+} // namespace python
+} // namespace blue_sky
+#endif // #ifdef BSPY_EXPORTING_PLUGIN
+
diff --git a/bs_base_linear_solvers/src/stdafx.cpp b/bs_base_linear_solvers/src/stdafx.cpp
new file mode 100644
index 0000000..3b9e69b
--- /dev/null
+++ b/bs_base_linear_solvers/src/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// bs_base_linear_solvers.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "bs_base_linear_solvers_stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/bs_base_linear_solvers/src/tfqmr.cpp b/bs_base_linear_solvers/src/tfqmr.cpp
new file mode 100644
index 0000000..fe3d331
--- /dev/null
+++ b/bs_base_linear_solvers/src/tfqmr.cpp
@@ -0,0 +1,351 @@
+/**
+ * \file tfqmr.cpp
+ * \brief TFQMR linear solver impl
+ * \author Salimgareeva E.M. (algorithm from "A fast Lanczos-type solver for nonsymmetric linear systems", P.Sonneveld)
+ * \date 11.02.2009
+ * */
+#include "bs_base_linear_solvers_stdafx.h"
+#include "linear_solvers.h"
+#include "tfqmr.h"
+#include "lin_solv_macro.h"
+
+#include BS_FORCE_PLUGIN_IMPORT ()
+#include "save_seq_vector.h"
+#include BS_STOP_PLUGIN_IMPORT ()
+
+namespace blue_sky
+ {
+
+ //////////////////////////////////////////////////////////////////////////
+ // tfqmr_solver
+
+ //! constructor
+ template
+ tfqmr_solver::tfqmr_solver (bs_type_ctor_param param)
+ : linear_solver_base (param)
+ {}
+
+ //! copy constructor
+ template
+ tfqmr_solver::tfqmr_solver(const tfqmr_solver &solver)
+ : bs_refcounter (), linear_solver_base (solver)
+ {
+ if (&solver != this)
+ *this = solver;
+ }
+
+ //! destructor
+ template
+ tfqmr_solver::~tfqmr_solver ()
+ {}
+
+
+ template
+ int tfqmr_solver::solve(matrix_t *matrix, rhs_item_array_t &rhs, item_array_t &solution)
+ {
+ return templ_solve (matrix, rhs, solution);
+ }
+
+ template
+ int tfqmr_solver::solve_prec(matrix_t *matrix, item_array_t &rhs, item_array_t &solution)
+ {
+ return templ_solve (matrix, rhs, solution);
+ }
+
+
+
+ /*!
+ * \brief TFQMR linear solver
+ *
+ * \param[in] matrix -- pointer to the matrix
+ * \param[in] rhs -- right hand side
+ * \param[out] solution -- solution
+ *
+ * \return 0 if success
+ */
+ template template
+ int tfqmr_solver::templ_solve(matrix_t *matrix1, rhs_t &rhs, item_array_t &solution)
+ {
+ BOSOUT (section::solvers, level::debug) << "TFQMR\n" << bs_end;
+ typedef item_t fp_type;
+
+ BS_ERROR (matrix1, "tfqmr_solve");
+ setup_preconditioner *setup_prec = dynamic_cast *> (static_cast (matrix1));
+
+ sp_bcsr_matrix_t matrix;
+ if (setup_prec)
+ {
+ setup_prec->prepare_matrix ();
+ matrix = setup_prec->get_prepared_matrix ();
+ BS_ASSERT (matrix);
+ }
+ else
+ {
+ matrix = sp_bcsr_matrix_t (matrix1, bs_dynamic_cast ());
+ }
+
+ BS_ERROR (rhs.size (), "tfqmr_solve");
+ BS_ERROR (solution.size (), "tfqmr_solve");
+ BS_ERROR (base_t::prop, "tfqmr_solve");
+
+ const smart_ptr &lprop(this->prop);
+
+ fp_type rho_1, rho_2 = 1, alpha = 1, beta, sigma;
+ int iter;
+ const double epsmac = 1e-24;
+ fp_type r_norm = 0;
+ fp_type b_norm = 0;
+ fp_type den_norm = 0;
+ fp_type r_norm_old = 0;
+ fp_type w_norm = 0;
+ fp_type eta = 0;
+ fp_type nu = 0;
+ fp_type tau = 0;
+ fp_type c = 0;
+ //fp_type *x = solution;
+
+ //OMP_TIME_MEASURE_START (tfqmr_solve_timer);
+
+ item_t tol = this->prop->get_tolerance ();
+ tol *= tol;
+ //resid = prop->get_residuals ();
+ //convergence_rate = prop->get_convergence_rate ();
+
+ index_t max_iter = this->prop->get_max_iters ();
+ index_t n = matrix->n_rows * matrix->n_block_size;
+
+ item_array_t p (n);
+ item_array_t v (n);
+ item_array_t w (n);
+ item_array_t u (n);
+ item_array_t q (n);
+ item_array_t d (n);
+ item_array_t res (n);
+ item_array_t r (n);
+ item_array_t rtilde (n);
+ item_array_t tmp (n);
+ item_array_t rhat (n);
+ item_array_t y (n);
+ //x_cgs = y + n;
+
+ lprop->set_success (0);
+
+ // solution = {0}
+ solution.assign (n, 0);
+ // r = {0}
+ r.assign (n, 0);
+ // TODO:paste
+ tmp.assign (n, 0);
+ p.assign (n, 0);
+ v.assign (n, 0);
+ q.assign (n, 0);
+ d.assign (n, 0);
+
+ // r = Ax0 - b
+ matrix->calc_lin_comb (-1.0, 1.0, solution, rhs, r);
+ rtilde.assign (r.begin (), r.end ());
+
+ // p0 = u0 = r0;
+ //memcpy (p, r, n * sizeof (double));
+ u.assign (r.begin (), r.end ());
+ p.assign (r.begin (), r.end ());
+ w.assign (r.begin (), r.end ());
+
+ // tmp = M^(-1) * u;
+ if (this->prec)
+ {
+ if (base_t::prec->solve_prec (matrix, u, tmp))
+ {
+ bs_throw_exception ("TFQMR: Preconditioner failed");
+ }
+ u.assign (tmp.begin (), tmp.end ());
+ p.assign (u.begin (), u.end ());
+ }
+
+ matrix->matrix_vector_product (p, v);
+
+ //tools::save_seq_vector (tools::string_formater ("1_well_bhp.%s.txt", it->first).str).save (it->second);
+
+ r_norm = bos_helper::mv_vector_inner_product (r, r);
+
+
+ if (r_norm <= tol) // initial guess quite good
+ return 0;
+
+ tau = sqrt (r_norm);
+ rho_1 = r_norm;
+ rho_2 = r_norm;
+ b_norm = sqrt (bos_helper::mv_vector_inner_product (rhs, rhs));
+
+
+ if (b_norm > epsmac) // choose convergence criterion
+ {
+ // |r_i|/|b| <= eps if |b| > 0
+ tol *= b_norm;
+ den_norm = b_norm;
+ }
+ else // (r_norm > epsmac)
+ {
+ // |r_i|/|r0| <= eps if |b| = 0
+ tol *= r_norm;
+ den_norm = r_norm;
+ }
+
+ // set up initial norm and convergense factor
+ lprop->set_relative_factor (den_norm);
+
+ index_t m, count;
+ // main loop
+ for (iter = 0; iter < max_iter; ++iter)
+ {
+ //printf ("TFQMR iteration: %d, resid = %le\n", iter, r_norm);
+ //fflush (stdout);
+ // TODO: paste
+ if (iter)
+ {
+ //rho_1 = mv_vector_inner_product (r, rtilde, n);//in first iter equals to r_norm
+ if (rho_1 == 0) // failure
+ {
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+ bs_throw_exception ("TFQMR: Failure - rho_1 == 0");
+ }
+ sum_vector (u, 1., res, beta, p); //p[n] = u[n]+beta*res
+
+ v.assign (n, 0);
+ matrix->matrix_vector_product (p, v); //v[n]=Ap[n]
+ }
+
+ sigma = bos_helper::mv_vector_inner_product (rtilde, v); //sigma=(rtilde,v[n-1])
+
+ alpha = rho_1/sigma;
+
+ // tmp = M^(-1)*v
+ if (this->prec)
+ {
+ if (base_t::prec->solve_prec (matrix, v, tmp))
+ {
+ bs_throw_exception ("TFQMR: Preconditioner failed");
+ }
+ v.assign (tmp.begin (), tmp.end ());
+ }
+
+ sum_vector (u, 1., v, -alpha, q); //q[n] = u[n-1]-alpha*v[n-1]
+ sum_vector (u, 1., q, 1., res); //res = u[n-1]+q[n]
+
+ tmp.assign (n, 0);
+ matrix->matrix_vector_product (res, tmp);// tmp=A*res
+ sum_vector (r, 1., tmp, -alpha, r);// r=r-alpha*res
+
+ //r_norm_old = r_norm;
+ r_norm = bos_helper::mv_vector_inner_product (r, r);
+
+ for (m = 1; m <= 2 ; m++)
+ {
+ if (m == 1) // m is odd
+ {
+ y.assign (u.begin (), u.end ());
+ w_norm = sqrt(r_norm * r_norm_old);
+ }
+ else // m is even
+ {
+ y.assign (q.begin (), q.end ());
+ w_norm = sqrt(r_norm);
+ }
+
+ sum_vector (y, 1., d, eta*nu*nu/alpha, d); //d[m] = y[m] + (eta[m-1]*nu[m-1]^2/alpha[n-1])*d[m-1]
+ nu = w_norm/tau; //nu[m]=||w[m+1]||/tau[m-1]
+ c = 1./sqrt (1. + nu*nu);
+ tau = tau*c*nu; //tau[m]=tau[m-1]nu[m]c[m]
+ eta = c*c*alpha; //eta[m]=c[m]^2*alpha[n-1]
+ //SUM_VECTOR(x,d,1,alpha,x_cgs,k,n); //x_cgs[n] = x[2n-1]+alpha[n-1]*d[2n]
+ sum_vector (solution, 1., d, eta, solution); //x[m] = x[m-1]+eta[m]*d[m]
+ if (r_norm <= tol)
+ {
+ count = 1;
+ break;
+ }
+ }
+
+ if (r_norm <= tol)
+ break;
+
+ rho_1 = bos_helper::mv_vector_inner_product (r, rtilde, n);//in first iter equals to r_norm
+ beta = rho_1 / rho_2;
+
+ // rhat = M^(-1) * r;
+ if (this->prec)
+ {
+ if (base_t::prec->solve_prec (matrix, r, rhat))
+ {
+ bs_throw_exception ("TFQMR: Preconditioner failed");
+ }
+ }
+ else // no precondition (preconditioner=identity_matrix)
+ {
+ rhat.assign (r.begin (), r.end ());
+ }
+
+ sum_vector (rhat, 1., q, beta, u); //u[n] = r[n]+beta*q[n]
+ sum_vector (q, 1., p, beta, res); //res = q[n]+beta*p[n-1]
+
+ rho_2 = rho_1;
+ }
+
+ //TODO: end
+ lprop->set_iters (iter + 1);
+ lprop->set_success (1);
+
+ /*
+ //additional checking convergence
+ mv_calc_lin_comb (matrix, -1.0, 1.0, solution, rhs, r);
+ r_norm = mv_vector_inner_product (r, r, n);
+ */
+ if (den_norm > epsmac)
+ lprop->set_final_resid (r_norm / den_norm);
+ else
+ lprop->set_final_resid (r_norm);
+
+ //printf ("TFQMR OK! iters = %d, resid = %le\n", lprop->iters, lprop->final_resid);
+ //OMP_TIME_MEASURE_END (tfqmr_solve_timer);
+
+ return 0;
+ }
+
+ /**
+ * @brief setup for TFQMR
+ *
+ * @param matrix -- input matrix
+ *
+ * @return 0 if success
+ */
+ template int
+ tfqmr_solver::setup (matrix_t *matrix)
+ {
+ if (!matrix)
+ {
+ bs_throw_exception ("TFQMR: Passed matrix is null");
+ }
+
+ BS_ASSERT (base_t::prop);
+ if (base_t::prec)
+ {
+ return base_t::prec->setup (matrix);
+ }
+
+ return 0;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ BLUE_SKY_TYPE_STD_CREATE_T_DEF(tfqmr_solver, (class));
+ BLUE_SKY_TYPE_STD_COPY_T_DEF(tfqmr_solver, (class));
+
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (tfqmr_solver) , 1, (linear_solver_base), "tfqmr_solver_base_fi", "tfqmr linear solver", "TFQMR linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (tfqmr_solver) , 1, (linear_solver_base), "tfqmr_solver_base_di", "tfqmr linear solver", "TFQMR linear solver", false);
+ BLUE_SKY_TYPE_IMPL_T_EXT(1, (tfqmr_solver) , 1, (linear_solver_base), "tfqmr_solver_base_mixi", "TFQMR linear solver", "TFQMR linear solver", false);
+
+
+ }
diff --git a/bs_bos_core/SConscript.bs b/bs_bos_core/SConscript.bs
new file mode 100644
index 0000000..60840fa
--- /dev/null
+++ b/bs_bos_core/SConscript.bs
@@ -0,0 +1,55 @@
+import os
+Import ("*")
+
+lib_name = "bs_bos_core"
+tar_name = "bs_bos_core"
+
+env = custom_env.Clone ()
+env.Append (CPPPATH = ["include",
+ includes["bs_bos_core_base"],
+ includes["bs_matrix"],
+ includes["bs_base_linear_solvers"],
+ includes["bs_csr_ilu_prec"],
+ includes["bs_bos_core_data_storage"],
+ includes["bs_mesh_mpfa"],
+ includes["bs_scal"],
+ includes["bs_pvt"]
+ ] + includes["kernel"]
+ + includes["bs_mesh"]
+ )
+
+libs = ["blue_sky",
+ "bs_bos_core_base",
+ "bs_matrix",
+ "bs_base_linear_solvers",
+ "bs_csr_ilu_prec",
+ "bs_bos_core_data_storage",
+ "bs_scal",
+ "bs_pvt"
+ ]
+
+boost_libs = ["boost_date_time-mt"]
+
+if (env["cfl"] == "1") :
+ env.AppendUnique (CPPDEFINES = ["BS_BOS_CORE_USE_CSR_ILU_CFL_PREC"])
+
+if (env["hdf5"] == "1") :
+ env.AppendUnique (CPPDEFINES = defines["bs_hdf5_storage"], CPPPATH = includes["bs_hdf5_storage"])
+ libs = libs + ["bs_hdf5_storage"]
+
+if (build_kind == "debug") :
+ env.AppendUnique (LIBS = list_suffix (libs, "_d") + list_suffix (boost_libs, "-d"))
+ lib_name += "_d"
+elif (build_kind == "release") :
+ env.AppendUnique (LIBS = libs + boost_libs)
+
+bs_bos_core = env.SharedLibrary (target = os.path.join (tar_exe_plugin_dir, lib_name), source = files (["."]).sources)
+
+env.Alias (tar_name, bs_bos_core)
+Export ("bs_bos_core")
+
+if (env["install"] == 1) :
+ inst_tar = env.Install ("$plugins_prefix", bs_bos_core)
+ env.Alias (tar_name, inst_tar)
+
+
diff --git a/bs_bos_core/bs_bos_core.cbp b/bs_bos_core/bs_bos_core.cbp
new file mode 100644
index 0000000..ee34bb8
--- /dev/null
+++ b/bs_bos_core/bs_bos_core.cbp
@@ -0,0 +1,509 @@
+
+