Changeset 13689


Ignore:
Timestamp:
Oct 7, 2019 10:16:50 PM (2 months ago)
Author:
Christian Andersson
Message:

Updated the compression option and the sparse option. Related to ticket:5666

Location:
PyFMI/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • PyFMI/trunk/CHANGELOG

    r13664 r13689  
    22
    33--- PyFMI-2.5.5 ---
     4    * Changed default value for the sparse solver in CVode (if the
     5      systemsize is >100 and the non-zero pattern is less than 15% then
     6      a sparse solver is used) (ticket:5666)
     7    * Changed default value for Jacobian compression (if CVode is used
     8      and the systemsize is >10 then Jacobian compression is used) (ticket:5666)
    49    * Added option to specify if the variable descriptions should be
    510      stored or not in the result file (ticket:5846)
  • PyFMI/trunk/doc/sphinx/source/changelog.rst

    r13664 r13689  
    55
    66--- PyFMI-2.5.5 ---
     7    * Changed default value for the sparse solver in CVode (if the
     8      systemsize is >100 and the non-zero pattern is less than 15% then
     9      a sparse solver is used) (ticket:5666)
     10    * Changed default value for Jacobian compression (if CVode is used
     11      and the systemsize is >10 then Jacobian compression is used) (ticket:5666)
    712    * Added option to specify if the variable descriptions should be
    813      stored or not in the result file (ticket:5846)
  • PyFMI/trunk/src/pyfmi/fmi_algorithm_drivers.py

    r13571 r13689  
    4040N.int = N.int32
    4141
     42PYFMI_JACOBIAN_LIMIT = 10
     43PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT = 100
     44PYFMI_JACOBIAN_SPARSE_NNZ_LIMIT  = 0.15 #In percentage
    4245
    4346class FMIResult(JMResultBase):
     
    475478                self.with_jacobian = True
    476479            else:
    477                 self.with_jacobian = False
     480                fnbr, gnbr = self.model.get_ode_sizes()
     481                if fnbr >= PYFMI_JACOBIAN_LIMIT and solver == "CVode":
     482                    self.with_jacobian = True
     483                    if fnbr >= PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT:
     484                        try:
     485                            self.solver_options["linear_solver"]
     486                        except KeyError:
     487                            #Need to calculate the nnz.
     488                            [derv_state_dep, derv_input_dep] = self.model.get_derivatives_dependencies()
     489                            nnz = N.sum([len(derv_state_dep[key]) for key in derv_state_dep.keys()])+fnbr
     490                            if nnz/float(fnbr*fnbr) <= PYFMI_JACOBIAN_SPARSE_NNZ_LIMIT:
     491                                self.solver_options["linear_solver"] = "SPARSE"
     492                else:
     493                    self.with_jacobian = False
    478494
    479495    def _set_solver_options(self):
  • PyFMI/trunk/src/pyfmi/simulation/assimulo_interface.py

    r11190 r13689  
    617617        self._logging = logging
    618618        self._sparse_representation = False
     619        self._with_jacobian = with_jacobian
    619620       
    620621        if f_nbr > 0 and with_jacobian:
     
    985986
    986987    def initialize(self, solver):
    987        
    988988        if hasattr(solver,"linear_solver"):
    989989            if solver.linear_solver == "SPARSE":
  • PyFMI/trunk/tests/test_fmi.py

    r13601 r13689  
    456456           
    457457            assert res.solver.maxord == 1
     458       
     459        @testattr(stddist = True)
     460        def test_with_jacobian_option(self):
     461            model = Dummy_FMUModelME2([], "NoState.Example1.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME2.0"), _connect_dll=False)
     462            opts = model.simulate_options()
     463            opts["solver"] = "CVode"
     464            opts["result_handling"] = "none"
     465           
     466            from pyfmi.fmi_algorithm_drivers import AssimuloFMIAlg, PYFMI_JACOBIAN_LIMIT
     467           
     468            class TempAlg(AssimuloFMIAlg):
     469                def solve(self):
     470                    pass
     471           
     472            def run_case(expected, default="Default"):
     473                model.reset()
     474                res = model.simulate(final_time=1.5,options=opts, algorithm=TempAlg)
     475                assert res.options["with_jacobian"] == default, res.options["with_jacobian"]
     476                assert res.solver.problem._with_jacobian == expected, res.solver.problem._with_jacobian
     477           
     478            run_case(False)
     479           
     480            model.get_ode_sizes = lambda: (PYFMI_JACOBIAN_LIMIT+1, 0)
     481            run_case(True)
     482           
     483            opts["solver"] = "Radau5ODE"
     484            run_case(False)
     485           
     486            opts["solver"] = "CVode"
     487            opts["with_jacobian"] = False
     488            run_case(False, False)
     489           
     490            model.get_ode_sizes = lambda: (PYFMI_JACOBIAN_LIMIT-1, 0)
     491            opts["with_jacobian"] = True
     492            run_case(True, True)
     493       
     494        @testattr(stddist = True)
     495        def test_sparse_option(self):
     496            from pyfmi.fmi_algorithm_drivers import AssimuloFMIAlg, PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT, PYFMI_JACOBIAN_SPARSE_NNZ_LIMIT
     497           
     498            class TempAlg(AssimuloFMIAlg):
     499                def solve(self):
     500                    pass
     501           
     502            def run_case(expected_jacobian, expected_sparse, fnbr=0, nnz={}, set_sparse=False):
     503                class Sparse_FMUModelME2(Dummy_FMUModelME2):
     504                    def get_derivatives_dependencies(self):
     505                        return (nnz, {})
     506           
     507                model = Sparse_FMUModelME2([], "NoState.Example1.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME2.0"), _connect_dll=False)
     508                opts = model.simulate_options()
     509                opts["solver"] = "CVode"
     510                opts["result_handling"] = "none"
     511                if set_sparse:
     512                    opts["CVode_options"]["linear_solver"] = "SPARSE"
     513               
     514                model.get_ode_sizes = lambda: (fnbr, 0)
     515               
     516                res = model.simulate(final_time=1.5,options=opts, algorithm=TempAlg)
     517                assert res.solver.problem._with_jacobian == expected_jacobian, res.solver.problem._with_jacobian
     518                assert res.solver.linear_solver == expected_sparse, res.solver.linear_solver
     519           
     520            run_case(False, "DENSE")
     521            run_case(True, "DENSE",  PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT+1, {"Dep": [1]*PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT**2})
     522            run_case(True, "SPARSE", PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT+1, {"Dep": [1]*PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT})
     523            run_case(True, "SPARSE", PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT+1, {"Dep": [1]*PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT}, True)
    458524           
    459525class Test_FMUModelME2:
Note: See TracChangeset for help on using the changeset viewer.