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)
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)
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)
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])
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)
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, )
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)
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)
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()
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], )
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
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)
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
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)
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)
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", )
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)
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)
def test_unkeep_task(): init() f = func1(10, 20) with pytest.raises(ExaquteException): get_value_from_remote(f)
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)