Example #1
0
    def asynchronousFinalize(self, batch):
        """
        Method updating all global estimators with the contributions of the new batch.
        """

        # Postprocess on finished batches
        for level in range(len(self.batchIndices[batch])):
            # update global estimators
            mda.updateGlobalMomentEstimator_Task(
                self.indices[level].qoiEstimator,
                self.batchIndices[batch][level].qoiEstimator,
                self.indices[level].costEstimator,
                self.batchIndices[batch][level].costEstimator,
                batch,
            )
            # delete COMPSs future objects no longer needed
            delete_object(
                self.batchIndices[batch][level].costEstimator,
                *self.batchIndices[batch][level].qoiEstimator,
            )
            # Update model coefficients for cost, bias, variance with new observations
            self.updatePredictors()

        for level in range(len(self.indices)):
            # synchronize estimator needed for checking convergence and updating hierarchy
            self.indices[level].qoiEstimator = get_value_from_remote(
                self.indices[level].qoiEstimator)
            self.indices[level].costEstimator = get_value_from_remote(
                self.indices[level].costEstimator)
Example #2
0
 def test_update(self):
     # Choose a reasonable number of events
     numberOfEvents = int(self._randomGenerator.uniform(1, 11, 1))
     # Test for an index set of dimension 0 (single-level) and 1 (multi-level)
     for dim in (0, 1):
         # Draw samples
         samples = self._samples(dim, numberOfEvents)
         # Compute reference power sums
         if dim == 0:
             referencePowerSums = powerSumsDimension0(samples)
         elif dim == 1:
             referencePowerSums = powerSumsDimension1(samples)
         referencePowerSums = get_value_from_remote(referencePowerSums)
         # Create test estimator and update it with samples
         estimator = MultiMomentEstimator(order=4)
         estimator.update(samples)
         # Get power sums to be tested
         testedPowerSums = get_value_from_remote(estimator._powerSums)
         # Run sub-test for the current index set dimension
         with self.subTest(
                 msg=f"{'Multi' if dim==1 else 'Single'}-level update",
                 indexSetDimension=dim):
             # Check that the sample counter is right
             self.assertEqual(estimator.sampleNumber(), numberOfEvents)
             # Check every power sums against its reference value,
             # with a tolerance for tiny numerical errors
             for key, reference in referencePowerSums.items():
                 self.assertAlmostEqual(self.distance(testedPowerSums[key] -
                                                      reference),
                                        0,
                                        delta=1**-15)
Example #3
0
def test_task():
    init()
    assert 30 == get_value_from_remote(func1(10, 20, keep=True))

    v = func2(10, 20, keep=True)
    assert 30 == get_value_from_remote(v[0])
    assert 200 == get_value_from_remote(v[1])

    with pytest.raises(ExaquteException):
        func3(10, 20, keep=True)
Example #4
0
    def test_updateD0(self):
        # test sample number
        sample_count = get_value_from_remote(self._estimator.sampleNumber())
        self.assertEqual(sample_count, self.pointPerEvent * self.eventNumber)

        # test power sums
        power_sums = get_value_from_remote(self._estimator._powerSums)
        for key, ref in self.referencePowerSums.items():
            for c in range(self.variableDimension):
                with self.subTest(
                        msg=f"Single-level update, for component {c}",
                        powerSum=key,
                        component=c):
                    self.assertEqual(power_sums[key][c], ref[c])
Example #5
0
    def update(self, samples):
        """
        Method updating the power sums and number of realizations, given new samples. The new
        data is passed through as a list containing power sums, up to a given order, and the
        number of samples from which it was computed. For example, let us discretise a scalar
        time signal u into M time steps to obtain a vector U of length M. A power sum of order
        a is computed as S_a = \sum_{i=1}^{M} U[i]^a.
        Samples will have the following shape:
        [[[[S1], [S2], M]]] ,
        where S1 and S2 are power sums of order one and two, respectively, and M is the total
        number of terms in the power sum (equivalent to number of time steps times realizations).

        Inputs:
        - self: an instance of the class
        - samples: nest list of dimension 4. Axes are: event, MC index, power, component.
        """
        # Synchronise if this estimator does support parallel computations
        if not self._isUpdateParallel:
            samples = get_value_from_remote(samples)
        # Deduce from self._indexSetDimension whether this is the initial update
        if self._indexSetDimension is None:
            # Guess missing information from sample set
            self._indexSetDimension = self._guessIndexSetDimension(samples[0])
            if self._variableDimension is None:
                self._variableDimension = self._guessVariableDimension(
                    samples[0])
            if self.order is None:
                self.order = self._guessOrder(samples[0])
            # Initialise power sums and their updater if they are not set
            if self._powerSums is None or self._powerSumsUpdater is None:
                self._initialisePowerSums()
        #
        # Proceed to update
        self._powerSums, self._sampleCounter = self._powerSumsUpdater(
            self._powerSums, self._sampleCounter, samples)
Example #6
0
    def multiValue(
        self,
        order: int,
        isError: bool = False,
        component: ListIndex = slice(None, None),
        isCentral: Union[bool, None] = None,
    ) -> HStatistics:
        """
        Function returning a specific order moment, its error estimate or both.

        Inputs:
        1. order: order of the moment
        2. isError: whether to return the error of the estimation (as opposed to the estimation
        itself).
        3. component: index (or indices) of components of the multi-valued random variable to
        consider
        4. isCentral: whether the moment is central (as opposed to raw)

        Outputs: float if component is an integer, list of floats otherwise.
        """
        # Assign missing values
        if isCentral is None:
            # Assume that any moment of order > 1 is requested as central
            isCentral = order > 1
        #
        if not self._isEstimationParallel:
            self._powerSums = get_value_from_remote(self._powerSums)
        return self._estimation(
            component,
            self._powerSums,
            self.sampleNumber(),
            order,
            isError,
            isCentral,
        )
Example #7
0
    def update(self, samples: SampleArray):
        """
        Method to update the power sums from new samples.

        Input arguments:
        1. samples: nested list of depth ≥ 3. (S_ijk) with: i the random event; j the solver
        level; k the component of the multi-valued random variable.
        """
        # Synchronise if this estimator does support parallel computations
        if not self._isUpdateParallel:
            samples = get_value_from_remote(samples)
        # Check proper format
        if not isinstance(samples, list) or not isinstance(samples[0], list):
            raise TypeError("Input argument is expected to be a list of lists")
        # At first update, initialise if necessary
        if self.sampleNumber() < 1:
            # Guess missing information from sample set
            if self._indexSetDimension is None:
                self._indexSetDimension = self._guessIndexSetDimension(
                    samples[0])
            if self._variableDimension is None:
                self._variableDimension = self._guessVariableDimension(
                    samples[0])
            # Initialise power sums and their updater if they are not set
            if self._powerSums is None:
                self._initialisePowerSums()
        # Proceed to update
        self._powerSums = self._powerSumsUpdater(self._powerSums, samples)
        self._addData(samples)
Example #8
0
def test_task_chaining():
    init()
    f = func1(10, 20)
    g = func1(f, 70, keep=True)
    assert get_value_from_remote(g) == 100

    with pytest.raises(ExaquteException):
        func1(f, 70)
Example #9
0
    def update(self, newHierarchy):
        """
        Add and process new samples. It first runs updateIndexSet, then calls on each indexs update, then calls updatePredictor.
        """

        # Add new indices and trim ones no longer required
        self.updateIndexSet(newHierarchy)

        for i in range(len(self.indices)):
            self.indices[i].update(newHierarchy[i])

        # synchronize estimator needed for checking convergence and updating hierarchy
        for i, index in enumerate(self.indices):
            self.indices[i].qoiEstimator = get_value_from_remote(
                index.qoiEstimator)
            self.indices[i].costEstimator = get_value_from_remote(
                index.costEstimator)

        # TODO Find a way to update predictors before sync?
        # Update models with new observations
        self.updatePredictors()
Example #10
0
 def test_estimationD0(self):
     for order, isError in itproduct(range(1, self.order + 1),
                                     (False, True)):
         key = f"h{order}{'_var' if isError else ''}"
         estimation = get_value_from_remote(
             self._estimator.multiValue(order, isError))
         for c in range(self.variableDimension):
             with self.subTest(
                     msg=
                 (f"{'Variance of ' if isError else ''}h-statistics of order {order}, "
                  f"component {c}"),
                     powerSum=key,
                     component=c,
             ):
                 self.assertAlmostEqual(
                     estimation[c],
                     self.referenceStatistics[key][c],
                 )
Example #11
0
    def asynchronousFinalizeIteration(self):
        """
        Method finalizing an iteration of the asynchornous framework. It synchronizes and calls all relevant methods of one single batch, the first available, before estimating convergence.
        """

        continue_iterating = True
        for batch in range(self.monteCarloSampler.numberBatches):
            if (
                self.monteCarloSampler.batchesLaunched[batch] is True
                and self.monteCarloSampler.batchesExecutionFinished[batch] is True
                and self.monteCarloSampler.batchesAnalysisFinished[batch] is True
                and self.monteCarloSampler.batchesConvergenceFinished[batch] is not True
                and continue_iterating is True
            ):
                continue_iterating = False
                self.monteCarloSampler.asynchronousFinalize(batch)
                flag = self.stoppingCriterionFlag(self.iterationCounter)
                self.monteCarloSampler.batchesConvergenceFinished[batch] = True
                break
        # screen iteration informations
        errors = get_value_from_remote(self.errorEstimation(self.errorsForStoppingCriterion))
        dTol = "None"
        tols = self.tolerances()
        if tols:
            dTol = " ".join(["{t:.3e}".format(t=tol) for tol in tols])
        print(
            "Iteration ",
            self.iterationCounter,
            "\tTolerance - ",
            dTol,
            "\tError - ",
            ["%.3e" % err for err in errors],
            "\tHierarchy - ",
            self.hierarchy(),
        )
        # update tolerance and hierarchy space if required
        if flag["updateTolerance"]:
            self.updateTolerance()
        if flag["updateIndexSpace"]:
            self.updateHierarchySpace()
        # update iteration counter
        self.iterationCounter += 1
        return flag
Example #12
0
    def test_estimation_deterministic(self):
        """
        Test estimation with respect to reference data.
        The reference data is generated by multi-moment_test_data.py
        """
        # Data for deterministic tests
        # The data is assumed to be small, so we store it all
        with open("parameters/multi-moment_test_data.json", "r") as f:
            referenceData = load(f)

        for dim, order, isError in itproduct((0, 1), (1, 2, 3, 4),
                                             (False, True)):
            referenceKey = f"{'Delta-' if dim == 1 else ''}h{order}{'_var' if isError else ''}"
            reference = referenceData[referenceKey]
            # Compute estimation
            estimator = MultiMomentEstimator(order=order)
            samples = referenceData["samples"]
            if dim == 0:
                # Extract samples from coarser (i.e. second) level, but preserve depth
                samples = [[s[1]] for s in samples]
            estimator.update(samples)
            estimation = get_value_from_remote(
                estimator.multiValue(order, isError))
            # Test each component individually
            for c, (est, ref) in enumerate(zip(estimation, reference)):
                if ref != 0:
                    # Consider relative error if possible
                    tol = abs(self.tolerance * ref)
                else:
                    # Absolute error is considered
                    tol = self.tolerance
                with self.subTest(
                        msg=
                    (f"{'Variance of ' if isError else ''}{'Delta ' if dim==1 else ''}"
                     f"h-statistics of order {order}, component {c}"),
                        indexSetDimension=dim,
                        statisticalOrder=order,
                        errorEstimation=isError,
                        component=c,
                ):
                    self.assertAlmostEqual(est, ref, delta=tol)
Example #13
0
    def stoppingCriterionFlag(self, currentCost=None):
        """
        Call stoppingCriterion.flag with the proper arguments and return its output
        (a.k.a flag).
        Input argument: currentCost is an indication of the cost the algorithm has entailed
        so far; we usually use the number of iterations.
        Output argument: criterion flag structure as define in the MultiCriterion class.
        """
        # Get errors required for stopping criterion
        errors = self.errorEstimation(self.errorsForStoppingCriterion)

        # Set up dictionary required for stoppingCriterion.flag
        input_dictionary = {}
        for i in range(len(errors)):
            input_dictionary["error" + str(i)] = get_value_from_remote(errors[i])
        input_dictionary["hierarchy"] = self.hierarchy()
        input_dictionary["algorithmCost"] = currentCost

        # Compute flag from dictionary and return
        flag = self.stoppingCriterion.flag(input_dictionary)
        return flag
Example #14
0
 def test_estimation_random(self):
     """
     Randomised testing of the estimations. False failures are possible.
     """
     for dim, order, isError in itproduct((0, 1), (1, 2, 3, 4),
                                          (False, True)):
         not_implemented = dim == 1 or (isError and order > 2)
         if not_implemented:
             # Nothing to do
             continue
         if isError:
             reference = gaussianHStatVariance(self.variance, order,
                                               self.numberOfSamples)
         else:
             if order == 1:
                 # order 1: not actually a h-statistics
                 reference = gaussianRawMoment(self.mean, self.variance,
                                               order)
             else:
                 reference = gaussianCentralMoment(self.variance, order)
         me = MultiMomentEstimator(order=order)
         me.update(self._samples(dim))
         estimation = get_value_from_remote(me.multiValue(order, isError))
         # Test each component individually
         for c, (est, ref) in enumerate(zip(estimation, reference)):
             # Consider relative error if possible
             tol = abs(self.tolerance * ref)
             if tol == 0:
                 # Absolute error is considered
                 tol = self.tolerance
             with self.subTest(
                     msg=
                 (f"{'Variance of ' if isError else ''}{'Delta ' if dim==1 else ''}"
                  f"h-statistics of order {order}, component {c}"),
                     indexSetDimension=dim,
                     statisticalOrder=order,
                     errorEstimation=isError,
                     component=c,
             ):
                 self.assertAlmostEqual(est, ref, delta=tol)
    def InitializeSolutionStep(self):
        self.current_model_part.RemoveSubModelPart("fluid_computational_model_part")
        self.step = self.current_model_part.ProcessInfo[KratosMultiphysics.STEP]
        KratosMultiphysics.ModelPartIO(self.auxiliary_mdpa_path, KratosMultiphysics.IO.WRITE | KratosMultiphysics.IO.MESH_ONLY).WriteModelPart( self.current_model_part)

        initial_time = time.time()
        self._RunXMC()
        elapsed_time = time.time() - initial_time

        if self.risk_measure == "expected_value":
            order = 1 ; is_central = False
        elif self.risk_measure == "variance":
            order = 2 ; is_central = True

        if not self.output_dict_results_file_name == "":
            self.results_dict[self.step] = {}

        # save lift coefficient
        qoi_counter = 0
        estimator_container = [] # here we append the estimator for each index/level
        error_container = [] # here we append the variance of the estimator for each index/level
        n_samples_container = []
        for index in range (len(self.xmc_analysis.monteCarloSampler.indices)):
            self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter] = get_value_from_remote(self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter])
            estimator_container.append(float(get_value_from_remote(self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter].value(order=order, isCentral=is_central))))
            error_container.append(float(get_value_from_remote(self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter].value(order=order, isCentral=is_central, isErrorEstimationRequested=True)[1])))
            n_samples_container.append(int(get_value_from_remote(self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter]._sampleCounter)))
        qoi_counter += 1
        # linearly sum estimators: this summation operation is valid for expected value and central moments
        # we refer to equation 4 of Krumscheid, S., Nobile, F., & Pisaroni, M. (2020). Quantifying uncertain system outputs via the multilevel Monte Carlo method — Part I: Central moment estimation. Journal of Computational Physics. https://doi.org/10.1016/j.jcp.2020.109466
        self._value = sum(estimator_container)
        # compute statistical error as in section 2.2 of
        # Pisaroni, M., Nobile, F., & Leyland, P. (2017). A Continuation Multi Level Monte Carlo (C-MLMC) method for uncertainty quantification in compressible inviscid aerodynamics. Computer Methods in Applied Mechanics and Engineering, 326, 20–50. https://doi.org/10.1016/j.cma.2017.07.030
        statistical_error = math.sqrt(sum(error_container))

        if not self.output_dict_results_file_name == "":
            self.results_dict[self.step]["run_time"]=elapsed_time
            self.results_dict[self.step]["number_of_samples"]=n_samples_container
            self.results_dict[self.step]["lift_coefficient"]={}
            self.results_dict[self.step]["lift_coefficient"]["risk_measure"]=self.risk_measure
            self.results_dict[self.step]["lift_coefficient"]["value"]=self._value
            self.results_dict[self.step]["lift_coefficient"]["statistical_error"]=statistical_error

        # save pressure coefficient
        pressure_dict = {}
        member = 0
        for node in self.current_model_part.GetSubModelPart(self.design_surface_sub_model_part_name).Nodes:
            estimator_container = [] # here we append contribution for each index/level
            variance_container = [] # here we append contribution for each index/level
            for index in range (len(self.xmc_analysis.monteCarloSampler.indices)):
                self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter] = get_value_from_remote(self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter])
                estimator_container.append(float(get_value_from_remote(self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter].multiValue(order=order, component = member, isCentral=is_central))))
                variance_container.append(float(get_value_from_remote(self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter].multiValue(order=2, component = member, isCentral=True))))
            pressure_coefficient = sum(estimator_container) # sum raw/central moment estimations on different indeces/levels
            variance_pressure_coefficient = sum(variance_container) # sum raw/central moment estimations on different indeces/levels
            member += 1
            pressure_dict[node.Id] = {}
            pressure_dict[node.Id]["coordinates"] = [node.X, node.Y, node.Z]
            pressure_dict[node.Id]["pressure_coefficient"] = pressure_coefficient
            pressure_dict[node.Id]["variance_pressure_coefficient"] = variance_pressure_coefficient
            node.SetValue(KratosMultiphysics.PRESSURE_COEFFICIENT, pressure_coefficient)
        qoi_counter += 1
        if not self.output_pressure_file_path == "":
            with open(self.output_pressure_file_path+"/pressure_"+str(self.step)+".json", 'w') as fp:
                json.dump(pressure_dict, fp,indent=4, sort_keys=True)

        # save shape sensitivity
        member = 0
        for node in self.current_model_part.GetSubModelPart(self.design_surface_sub_model_part_name).Nodes:
            shape_sensitivity = KratosMultiphysics.Vector(3, 0.0)
            for idim in range(3):
                estimator_container = [] # here we append contribution for each index/level
                for index in range (len(self.xmc_analysis.monteCarloSampler.indices)):
                    self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter] = get_value_from_remote(self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter])
                    estimator_container.append(float(get_value_from_remote(self.xmc_analysis.monteCarloSampler.indices[index].qoiEstimator[qoi_counter].multiValue(order=order, component = member, isCentral=is_central))))
                shape_sensitivity[idim] = sum(estimator_container) # sum raw/central moment estimations on different indeces/levels
                member += 1

            node.SetValue(KratosMultiphysics.SHAPE_SENSITIVITY, shape_sensitivity)
Example #16
0
    def test_mc_Kratos(self):
        if not isKratosFound():
            self.skipTest(
                "Missing dependency: KratosMultiphysics or one of required applications. Check the test docstrings for details."
            )

        # read parameters
        parametersList = [
            "poisson_square_2d/problem_settings/parameters_xmc_test_mc_Kratos_asynchronous_poisson_2d.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mc_Kratos_asynchronous_poisson_2d_RFF.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mc_Kratos_asynchronous_poisson_2d_with_combined_power_sums.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mc_Kratos_asynchronous_poisson_2d_with_10_combined_power_sums.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mc_Kratos_poisson_2d.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mc_Kratos_poisson_2d_with_combined_power_sums.json",
            "poisson_square_2d/problem_settings/poisson_multi-moment_mc.json",
        ]

        for parametersPath in parametersList:
            with open(parametersPath, "r") as parameter_file:
                parameters = json.load(parameter_file)
            # SolverWrapper
            parameters["solverWrapperInputDictionary"][
                "qoiEstimator"] = parameters["monteCarloIndexInputDictionary"][
                    "qoiEstimator"]
            # SampleGenerator
            samplerInputDictionary = parameters["samplerInputDictionary"]
            samplerInputDictionary[
                "randomGeneratorInputDictionary"] = parameters[
                    "randomGeneratorInputDictionary"]
            samplerInputDictionary[
                "solverWrapperInputDictionary"] = parameters[
                    "solverWrapperInputDictionary"]
            # MonteCarloIndex
            monteCarloIndexInputDictionary = parameters[
                "monteCarloIndexInputDictionary"]
            monteCarloIndexInputDictionary[
                "samplerInputDictionary"] = samplerInputDictionary
            # MonoCriterion
            criteriaArray = []
            criteriaInputs = []
            for monoCriterion in parameters["monoCriteriaInputDictionary"]:
                criteriaArray.append(
                    xmc.monoCriterion.MonoCriterion(
                        parameters["monoCriteriaInputDictionary"]
                        [monoCriterion]["criteria"],
                        parameters["monoCriteriaInputDictionary"]
                        [monoCriterion]["tolerance"],
                    ))
                criteriaInputs.append([
                    parameters["monoCriteriaInputDictionary"][monoCriterion]
                    ["input"]
                ])
            # MultiCriterion
            multiCriterionInputDictionary = parameters[
                "multiCriterionInputDictionary"]
            multiCriterionInputDictionary["criteria"] = criteriaArray
            multiCriterionInputDictionary[
                "inputsForCriterion"] = criteriaInputs
            criterion = xmc.multiCriterion.MultiCriterion(
                **multiCriterionInputDictionary)
            # ErrorEstimator
            statErrorEstimator = xmc.errorEstimator.ErrorEstimator(
                **parameters["errorEstimatorInputDictionary"])
            # HierarchyOptimiser
            hierarchyCostOptimiser = xmc.hierarchyOptimiser.HierarchyOptimiser(
                **parameters["hierarchyOptimiserInputDictionary"])
            # EstimationAssembler
            if ("expectationAssembler" in
                    parameters["estimationAssemblerInputDictionary"].keys()):
                expectationAssembler = xmc.estimationAssembler.EstimationAssembler(
                    **parameters["estimationAssemblerInputDictionary"]
                    ["expectationAssembler"])
            if "varianceAssembler" in parameters[
                    "estimationAssemblerInputDictionary"].keys():
                varianceAssembler = xmc.estimationAssembler.EstimationAssembler(
                    **parameters["estimationAssemblerInputDictionary"]
                    ["varianceAssembler"])
            # MonteCarloSampler
            monteCarloSamplerInputDictionary = parameters[
                "monteCarloSamplerInputDictionary"]
            monteCarloSamplerInputDictionary[
                "indexConstructorDictionary"] = monteCarloIndexInputDictionary
            monteCarloSamplerInputDictionary["assemblers"] = [
                expectationAssembler,
                varianceAssembler,
            ]
            monteCarloSamplerInputDictionary["errorEstimators"] = [
                statErrorEstimator
            ]
            mcSampler = xmc.monteCarloSampler.MonteCarloSampler(
                **monteCarloSamplerInputDictionary)
            # XMCAlgorithm
            XMCAlgorithmInputDictionary = parameters[
                "XMCAlgorithmInputDictionary"]
            XMCAlgorithmInputDictionary["monteCarloSampler"] = mcSampler
            XMCAlgorithmInputDictionary[
                "hierarchyOptimiser"] = hierarchyCostOptimiser
            XMCAlgorithmInputDictionary["stoppingCriterion"] = criterion
            algo = xmc.XMCAlgorithm(**XMCAlgorithmInputDictionary)

            if parameters["solverWrapperInputDictionary"][
                    "asynchronous"] is True:
                algo.runAsynchronousXMC()
            else:
                algo.runXMC()

            # test
            estimations = get_value_from_remote(algo.estimation())
            estimated_mean = 1.5
            self.assertAlmostEqual(estimations[0], estimated_mean, delta=0.1)
            self.assertEqual(algo.hierarchy()[0][1], 15)
Example #17
0
    def runXMC(self):
        """
        Run an algorithm with generic structure.
        """

        self.checkInitialisation(self)

        # Iteration Loop will start here
        flag = self.stoppingCriterion.flagStructure()
        self.iterationCounter = 0
        # print("Beginning Iterations for tolerance ", self.tolerances(self.errorsForStoppingCriterion)) #TODO not very robust
        while not flag["stop"]:
            # TODO Mostly outdated. Must be thoroughly checked.
            newHierarchy, splittingParameter = self.optimalHierarchy()

            self.splitTolerance(splittingParameter)

            self.updateHierarchy(newHierarchy)

            # synchronization point needed to launch new tasks if convergence is false
            # put the synchronization point as in the end as possible
            # TODO: remove from here the synchronization point to more hidden places
            flag = self.stoppingCriterionFlag(self.iterationCounter)
            flag = get_value_from_remote(flag)

            # TODO Display selection is mostly guesswork here (very fragile)
            errors = get_value_from_remote(
                self.errorEstimation(self.errorsForStoppingCriterion)
            )
            dErrors = " ".join(["{err:.3e}".format(err=float(error)) for error in errors])
            dHierarchy = " ".join([str(i[1]) for i in self.hierarchy()])
            dTol = "None"
            tols = self.tolerances(splittingParameter)
            if tols:
                dTol = " ".join(["{t:.3e}".format(t=tol) for tol in tols])
            print(
                f"Iteration — {self.iterationCounter}",
                f"Tolerances — {dTol}",
                f"Errors — {dErrors}",
                f"Hierarchy — {dHierarchy}",
                sep="\t",
            )

            if flag["updateTolerance"]:
                self.updateTolerance()
            if flag["updateIndexSpace"]:
                self.updateHierarchySpace()

            self.iterationCounter += 1

            #### DATA DUMP ##########
            if self.isDataDumped is True:
                pathObject = pl.Path(self.outputFolderPath)
                pathObject.mkdir(parents=True, exist_ok=True)
                filename = (
                    self.outputFolderPath
                    + "/iteration_"
                    + str(self.iterationCounter)
                    + ".pickle"
                )
                output_file = open(filename, "wb")

                output_dict = {}
                hier = self.hierarchy()
                output_dict["predictedHierarchy"] = newHierarchy
                output_dict["hierarchy"] = hier
                if len(self.predictorsForHierarchy) != 0:
                    qoip = self.predictor()
                    costp = self.costPredictor()
                    output_dict["biasParameters"] = qoip[0].parameters
                    output_dict["varParameters"] = qoip[1].parameters
                    output_dict["costParameters"] = costp.parameters

                output_dict["indexwiseBias"] = self.indexEstimation(0, [1, True, False])
                errs = self.indexEstimation(0, [1, True, True])
                levels, samples = splitOneListIntoTwo(hier)
                output_dict["indexwiseVar"] = [errs[i] * samples[i] for i in range(len(errs))]
                output_dict["indexwiseCost"] = self.indexCostEstimation([1, True, False])

                hier = newHierarchy
                levels, samples = splitOneListIntoTwo(hier)
                costs = self.indexCostEstimation([1, True, False])
                total_times = [sample * cost for sample, cost in zip(samples, costs)]
                output_dict["totalTime"] = sum(total_times)
                pickle.dump(output_dict, output_file)

        # TODO - Debug statement. Remove for PYCOMPSS tests
        displayEstimation = get_value_from_remote(self.estimation())
        displayEstimation = " ".join(["{e:.3e}".format(e=est) for est in displayEstimation])
        displayError = get_value_from_remote(
            self.errorEstimation(self.errorsForStoppingCriterion)
        )
        displayError = " ".join(["{e:.3e}".format(e=error) for error in displayError])
        displayCost = get_value_from_remote(self.indexCostEstimation([1, True, False]))
        displayCost = " ".join(["{c:.3e}".format(c=cost) for cost in displayCost])
        print(
            f"Estimations — {displayEstimation}",
            f"Final errors — {displayError}",
            f"Levelwise mean costs — {displayCost}",
            sep="\n",
        )
Example #18
0
    def optimalHierarchy(self):
        """
        Method that interfaces with the HierarchyOptimiser class to compute
        the optimal hierarchy
        """
        input_dict = self.hierarchyOptimiser.inputDictionaryTemplate()

        # No optimisation at first iteration
        if self.iterationCounter < 1:
            newHierarchy = self.hierarchyOptimiser.defaultHierarchy
            splittingParameter = input_dict.get("splittingParameter", None)
            return newHierarchy, splittingParameter

        # Else, assemble data for hierarchy optimiser

        # Random variables of interest
        # Indexwise estimations
        if self.estimatorsForHierarchy:
            input_dict["estimations"] = [
                get_value_from_remote(self.indexEstimation(c[0], c[1]))
                for c in self.estimatorsForHierarchy
            ]
        # Predictors
        if self.predictorsForHierarchy:
            input_dict["models"] = []
            input_dict["parametersForModel"] = []
            for coord in self.predictorsForHierarchy:
                input_dict["models"].append(self.predictor(coord)._valueForParameters)
                # TODO This should get self.predictor(coord).oldParameters
                # and default to self.predictor(coord).parameters if they are None
                params = get_value_from_remote(self.predictor(coord).oldParameters)
                if params is None:
                    params = get_value_from_remote(self.predictor(coord).parameters)
                input_dict["parametersForModel"].append(params)

        # Sample cost
        # Indexwise estimation
        if self.costEstimatorForHierarchy is not None:
            input_dict["costEstimations"] = self.indexCostEstimation(
                self.costEstimatorForHierarchy
            )

        # Predictor
        if self.costPredictor() is not None:
            input_dict["costModel"] = self.costPredictor()._valueForParameters
            # TODO This should get self.costPredictor().oldParameters
            # and default to self.costPredictor().parameters if they are None
            params = get_value_from_remote(self.costPredictor().oldParameters)
            if params is None:
                params = get_value_from_remote(self.costPredictor().parameters)
            params = input_dict["costParameters"]

        # Error parameters
        # TODO - Triple dereference below!! Add method to get errorEstimator parameters
        # or errorEstimator objects themselves from monteCarloSampler
        if self.errorParametersForHierarchy is not None:
            input_dict["errorParameters"] = [
                self.monteCarloSampler.errorEstimators[c].parameters
                for c in self.errorParametersForHierarchy
            ]

        # Miscellaneous parameters
        input_dict["newSampleNumber"] = 25  # TODO configurable, not hard-coded
        input_dict["oldHierarchy"] = self.hierarchy()
        input_dict["defaultHierarchy"] = self.hierarchyOptimiser.defaultHierarchy

        # Synchronisation
        input_dict = get_value_from_remote(input_dict)

        # Compute new hierarchy
        newHierarchy = self.hierarchyOptimiser.optimalHierarchy(input_dict)
        splittingParameter = input_dict.get("splittingParameter", None)
        return newHierarchy, splittingParameter
    def EvaluateQuantityOfInterest(self):
        """
        Method evaluating the QoI of the problem: int_{domain} TEMPERATURE(x,y) dx dy
        """
        KratosMultiphysics.CalculateNodalAreaProcess(self._GetSolver().main_model_part,2).Execute()
        Q = 0.0
        for node in self._GetSolver().main_model_part.Nodes:
            Q = Q + (node.GetSolutionStepValue(KratosMultiphysics.NODAL_AREA)*node.GetSolutionStepValue(KratosMultiphysics.TEMPERATURE))
        return Q


if __name__ == '__main__':

    # set the ProjectParameters.json path
    parameter_file_name = "problem_settings/project_parameters.json"
    # create a serialization of the model and of the project parameters
    pickled_model,pickled_parameters = SerializeModelParameters_Task(parameter_file_name)
    # set batch size and initialize qoi list where to append Quantity of Interests values
    batch_size = 20
    qoi = []
    # define the list for heat flux values
    heat_flux_list = np.random.beta(2.0,6.0,batch_size)
    # start algorithm
    for instance in range (0,batch_size):
        qoi.append(ExecuteInstance_Task(pickled_model,pickled_parameters,heat_flux_list,instance))

    # synchronize to local machine
    qoi = get_value_from_remote(qoi)
    print("\nqoi values:\n",qoi)
Example #20
0
    def mpi_test_mlmc_Kratos_ParMmg(self):

        # read parameters
        parametersList = [
            "problem_settings/parameters_xmc_asynchronous_mlmc_SAR.json",
            "problem_settings/parameters_xmc_asynchronous_mlmc_DAR.json",
        ]

        with WorkFolderScope("caarc_wind_mpi/", __file__, add_to_path=True):
            for parametersPath in parametersList:
                with open(parametersPath, "r") as parameter_file:
                    parameters = json.load(parameter_file)
                # SolverWrapper
                parameters["solverWrapperInputDictionary"][
                    "qoiEstimator"] = parameters[
                        "monteCarloIndexInputDictionary"]["qoiEstimator"]
                # SampleGenerator
                samplerInputDictionary = parameters["samplerInputDictionary"]
                samplerInputDictionary[
                    "randomGeneratorInputDictionary"] = parameters[
                        "randomGeneratorInputDictionary"]
                samplerInputDictionary[
                    "solverWrapperInputDictionary"] = parameters[
                        "solverWrapperInputDictionary"]
                # MonteCarloIndex Constructor
                monteCarloIndexInputDictionary = parameters[
                    "monteCarloIndexInputDictionary"]
                monteCarloIndexInputDictionary[
                    "samplerInputDictionary"] = samplerInputDictionary
                # MonoCriterion
                criteriaArray = []
                criteriaInputs = []
                for monoCriterion in parameters["monoCriteriaInputDictionary"]:
                    criteriaArray.append(
                        xmc.monoCriterion.MonoCriterion(
                            parameters["monoCriteriaInputDictionary"]
                            [monoCriterion]["criteria"],
                            parameters["monoCriteriaInputDictionary"]
                            [monoCriterion]["tolerance"],
                        ))
                    criteriaInputs.append([
                        parameters["monoCriteriaInputDictionary"]
                        [monoCriterion]["input"]
                    ])
                # MultiCriterion
                multiCriterionInputDictionary = parameters[
                    "multiCriterionInputDictionary"]
                multiCriterionInputDictionary["criteria"] = criteriaArray
                multiCriterionInputDictionary[
                    "inputsForCriterion"] = criteriaInputs
                criterion = xmc.multiCriterion.MultiCriterion(
                    **multiCriterionInputDictionary)
                # ErrorEstimator
                MSEErrorEstimator = xmc.errorEstimator.ErrorEstimator(
                    **parameters["errorEstimatorInputDictionary"])
                # HierarchyOptimiser
                hierarchyCostOptimiser = xmc.hierarchyOptimiser.HierarchyOptimiser(
                    **parameters["hierarchyOptimiserInputDictionary"])
                # MonteCarloSampler
                monteCarloSamplerInputDictionary = parameters[
                    "monteCarloSamplerInputDictionary"]
                monteCarloSamplerInputDictionary[
                    "indexConstructorDictionary"] = monteCarloIndexInputDictionary
                monteCarloSamplerInputDictionary["errorEstimators"] = [
                    MSEErrorEstimator
                ]
                # EstimationAssembler
                monteCarloSamplerInputDictionary["assemblers"] = []
                for key, dicArgs in parameters[
                        "estimationAssemblerInputDictionary"].items():
                    monteCarloSamplerInputDictionary["assemblers"].append(
                        xmc.estimationAssembler.EstimationAssembler(**dicArgs))
                mcSampler = xmc.monteCarloSampler.MonteCarloSampler(
                    **monteCarloSamplerInputDictionary)
                # XMCAlgorithm
                XMCAlgorithmInputDictionary = parameters[
                    "XMCAlgorithmInputDictionary"]
                XMCAlgorithmInputDictionary["monteCarloSampler"] = mcSampler
                XMCAlgorithmInputDictionary[
                    "hierarchyOptimiser"] = hierarchyCostOptimiser
                XMCAlgorithmInputDictionary["stoppingCriterion"] = criterion

                algo = xmc.XMCAlgorithm(**XMCAlgorithmInputDictionary)

                if parameters["solverWrapperInputDictionary"][
                        "asynchronous"] is True:
                    algo.runAsynchronousXMC()
                else:
                    algo.runXMC()

                # test
                # such results are not accurate, since we run the problem for few decimals
                # and coarse meshes instead of hundreds of seconds and finer meshes
                estimations = get_value_from_remote(algo.estimation())
                self.assertGreater(sum(estimations), 0)
                for level in algo.hierarchy():
                    self.assertEqual(level[1], 5)
                # check moment estimator - level 0
                sample_counter = (algo.monteCarloSampler.indices[0].
                                  qoiEstimator[0]._sampleCounter)
                S1 = get_value_from_remote(algo.monteCarloSampler.indices[0].
                                           qoiEstimator[0].powerSums[0][0])
                h1 = get_value_from_remote(
                    ccm.computeCentralMomentsOrderOneDimensionZero(
                        S1, sample_counter))
                self.assertGreater(-h1, 0)
                self.assertEqual(sample_counter, 5)
                # check multi moment estimator - level 1
                sample_counter = (algo.monteCarloSampler.indices[1].
                                  qoiEstimator[1]._sampleCounter)
                self.assertEqual(sample_counter, 5)
                # check combined moment estimator - level 2
                sample_counter = (algo.monteCarloSampler.indices[2].
                                  qoiEstimator[2]._sampleCounter)
                S1 = get_value_from_remote(algo.monteCarloSampler.indices[2].
                                           qoiEstimator[2].powerSums[0][0])
                h1 = get_value_from_remote(
                    ccm.computeCentralMomentsOrderOneDimensionZero(
                        S1, sample_counter))
                self.assertEqual(sample_counter, 5)
                # check multi combined moment estimator - level 2
                sample_counter = (algo.monteCarloSampler.indices[2].
                                  qoiEstimator[3]._sampleCounter)
                self.assertEqual(sample_counter, 5)
Example #21
0
def test_unkeep_task():
    init()
    f = func1(10, 20)
    with pytest.raises(ExaquteException):
        get_value_from_remote(f)
Example #22
0
    def test_mlmc_Kratos(self):
        if not isKratosFound():
            self.skipTest("Missing dependency: KratosMultiphysics or one of its applications")
        if not isMmgFound():
            self.skipTest(
                "Missing dependency: KratosMultiphysics.MeshingApplication with MMG support"
            )

        # read parameters
        parametersList = [
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_asynchronous_poisson_2d.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_asynchronous_poisson_2d_with_combined_power_sums.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_poisson_2d.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_poisson_2d_with_combined_power_sums.json",
            "poisson_square_2d/problem_settings/poisson_multi-moment_mlmc.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_asynchronous_poisson_2d_with_combined_power_sums_multi.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_asynchronous_poisson_2d_with_combined_power_sums_multi_ensemble.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_asynchronous_poisson_2d_DAR.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_asynchronous_poisson_2d_fixedsamples.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_asynchronous_adaptivefixednumberlevels_poisson_2d.json",
            "poisson_square_2d/problem_settings/parameters_xmc_test_mlmc_Kratos_adaptivefixednumberlevels_poisson_2d.json"
        ]


        for parametersPath in parametersList:
            # read parameters
            with open(parametersPath, "r") as parameter_file:
                parameters = json.load(parameter_file)
            # SolverWrapper
            parameters["solverWrapperInputDictionary"]["qoiEstimator"] = parameters[
                "monteCarloIndexInputDictionary"
            ]["qoiEstimator"]
            # SampleGenerator
            samplerInputDictionary = parameters["samplerInputDictionary"]
            samplerInputDictionary["randomGeneratorInputDictionary"] = parameters[
                "randomGeneratorInputDictionary"
            ]
            samplerInputDictionary["solverWrapperInputDictionary"] = parameters[
                "solverWrapperInputDictionary"
            ]
            # MonteCarloIndex Constructor
            monteCarloIndexInputDictionary = parameters["monteCarloIndexInputDictionary"]
            monteCarloIndexInputDictionary["samplerInputDictionary"] = samplerInputDictionary
            # MonoCriterion
            criteriaArray = []
            criteriaInputs = []
            for monoCriterion in parameters["monoCriteriaInputDictionary"]:
                criteriaArray.append(
                    xmc.monoCriterion.MonoCriterion(
                        parameters["monoCriteriaInputDictionary"][monoCriterion]["criteria"],
                        parameters["monoCriteriaInputDictionary"][monoCriterion]["tolerance"],
                    )
                )
                criteriaInputs.append(
                    [parameters["monoCriteriaInputDictionary"][monoCriterion]["input"]]
                )
            # MultiCriterion
            multiCriterionInputDictionary = parameters["multiCriterionInputDictionary"]
            multiCriterionInputDictionary["criteria"] = criteriaArray
            multiCriterionInputDictionary["inputsForCriterion"] = criteriaInputs
            criterion = xmc.multiCriterion.MultiCriterion(**multiCriterionInputDictionary)
            # ErrorEstimator
            MSEErrorEstimator = xmc.errorEstimator.ErrorEstimator(
                **parameters["errorEstimatorInputDictionary"]
            )
            # HierarchyOptimiser
            # Set tolerance from stopping criterion
            parameters["hierarchyOptimiserInputDictionary"]["tolerance"] = parameters["monoCriteriaInputDictionary"]["statisticalError"]["tolerance"]
            hierarchyCostOptimiser = xmc.hierarchyOptimiser.HierarchyOptimiser(
                **parameters["hierarchyOptimiserInputDictionary"]
            )
            # EstimationAssembler
            if (
                "expectationAssembler"
                in parameters["estimationAssemblerInputDictionary"].keys()
            ):
                expectationAssembler = xmc.estimationAssembler.EstimationAssembler(
                    **parameters["estimationAssemblerInputDictionary"]["expectationAssembler"]
                )
            if (
                "discretizationErrorAssembler"
                in parameters["estimationAssemblerInputDictionary"].keys()
            ):
                discretizationErrorAssembler = xmc.estimationAssembler.EstimationAssembler(
                    **parameters["estimationAssemblerInputDictionary"][
                        "discretizationErrorAssembler"
                    ]
                )
            if "varianceAssembler" in parameters["estimationAssemblerInputDictionary"].keys():
                varianceAssembler = xmc.estimationAssembler.EstimationAssembler(
                    **parameters["estimationAssemblerInputDictionary"]["varianceAssembler"]
                )
            # MonteCarloSampler
            monteCarloSamplerInputDictionary = parameters["monteCarloSamplerInputDictionary"]
            monteCarloSamplerInputDictionary[
                "indexConstructorDictionary"
            ] = monteCarloIndexInputDictionary
            monteCarloSamplerInputDictionary["assemblers"] = [
                expectationAssembler,
                discretizationErrorAssembler,
                varianceAssembler,
            ]
            monteCarloSamplerInputDictionary["errorEstimators"] = [MSEErrorEstimator]
            # build Monte Carlo sampler object
            mcSampler = xmc.monteCarloSampler.MonteCarloSampler(
                **monteCarloSamplerInputDictionary
            )
            # XMCAlgorithm
            XMCAlgorithmInputDictionary = parameters["XMCAlgorithmInputDictionary"]
            XMCAlgorithmInputDictionary["monteCarloSampler"] = mcSampler
            XMCAlgorithmInputDictionary["hierarchyOptimiser"] = hierarchyCostOptimiser
            XMCAlgorithmInputDictionary["stoppingCriterion"] = criterion
            algo = xmc.XMCAlgorithm(**XMCAlgorithmInputDictionary)

            if parameters["solverWrapperInputDictionary"]["asynchronous"] is True:
                algo.runAsynchronousXMC()
            else:
                algo.runXMC()

            # test
            estimations = get_value_from_remote(algo.estimation())
            estimated_mean = 1.47
            self.assertAlmostEqual(estimations[0], estimated_mean, delta=1.0)
            if "asynchronous_adaptivefixednumberlevels" in parametersPath:
                self.assertAlmostEqual(sum(estimations), 1.5285582403120515, delta=parameters["monoCriteriaInputDictionary"]["statisticalError"]["tolerance"][0])
                # self.assertEqual(sum(algo.hierarchy()[i][-1] for i in range (0,len(algo.hierarchy()))), 194) # uncomment once issue #62 is solved
            elif "adaptivefixednumberlevels" in parametersPath:
                self.assertAlmostEqual(sum(estimations), 1.528129424481246, delta=parameters["monoCriteriaInputDictionary"]["statisticalError"]["tolerance"][0])
                # self.assertEqual(sum(algo.hierarchy()[i][-1] for i in range (0,len(algo.hierarchy()))), 122) # uncomment once issue #62 is solved
            else:
                for level in algo.hierarchy():
                    self.assertEqual(level[1], 15)