From 9052442167af0f4737dee2458f3ff999aa046101 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 22 Jan 2021 14:47:10 +1100 Subject: [PATCH 01/29] (DEV) change model to be a collection of builders rather than features This will mean the model can be built without interpolating and might be good for inference --- .../modelling/core/geological_model_graph.py | 863 ++++++++++++++++++ .../features/geological_feature_builder.py | 20 +- 2 files changed, 879 insertions(+), 4 deletions(-) create mode 100644 LoopStructural/modelling/core/geological_model_graph.py diff --git a/LoopStructural/modelling/core/geological_model_graph.py b/LoopStructural/modelling/core/geological_model_graph.py new file mode 100644 index 000000000..959e627d5 --- /dev/null +++ b/LoopStructural/modelling/core/geological_model_graph.py @@ -0,0 +1,863 @@ +""" +Main entry point for creating a geological model +""" +import logging + +import numpy as np +import pandas as pd +from LoopStructural.datasets import normal_vector_headers +from LoopStructural.interpolators.discrete_fold_interpolator import \ + DiscreteFoldInterpolator as DFI +from LoopStructural.interpolators.finite_difference_interpolator import \ + FiniteDifferenceInterpolator as FDI +from LoopStructural.interpolators.piecewiselinear_interpolator import \ + PiecewiseLinearInterpolator as PLI + +try: + from LoopStructural.interpolators.surfe_wrapper import \ + SurfeRBFInterpolator as Surfe + + surfe = True + +except ImportError: + surfe = False + +from LoopStructural.interpolators.structured_grid import StructuredGrid +from LoopStructural.interpolators.structured_tetra import TetMesh +from LoopStructural.modelling.fault.fault_segment import FaultSegment +from LoopStructural.modelling.features import (GeologicalFeatureInterpolator, + RegionFeature, + StructuralFrameBuilder, + UnconformityFeature) +from LoopStructural.modelling.fold import FoldRotationAngle +from LoopStructural.modelling.fold.fold import FoldEvent +from LoopStructural.modelling.fold.foldframe import FoldFrame +from LoopStructural.utils.exceptions import LoopBaseException +from LoopStructural.utils.helper import (all_heading, gradient_vec_names, + strike_dip_vector) + +from LoopStructural.utils import getLogger, log_to_file +logger = getLogger(__name__) +if not surfe: + logger.warning("Cannot import Surfe") + + +def _calculate_average_intersection(series_builder, fold_frame, fold, + **kwargs): + """ + + Parameters + ---------- + series_builder + fold_frame + fold + + Returns + ------- + + """ + l2 = fold_frame.calculate_intersection_lineation( + series_builder) + fold.fold_axis = np.mean(l2, axis=0) + + +class GeologicalModel: + """ + A geological model is the recipe for building a 3D model and can include + the rescaling of the model between 0 and 1. + + Attributes + ---------- + features : list + Contains all features youngest to oldest + feature_name_index : dict + maps feature name to the list index of the features + data : pandas dataframe + the dataframe used for building the geological model + nsteps : tuple/np.array(3,dtype=int) + the number of steps x,y,z to evaluate the model + origin : tuple/np.array(3,dtype=doubles) + the origin of the model box + parameters : dict + a dictionary tracking the parameters used to build the model + scale_factor : double + the scale factor used to rescale the model + + + """ + def __init__(self, origin, maximum, rescale=True, nsteps=(40, 40, 40), + reuse_supports=False, logfile=None, loglevel='info'): + """ + Parameters + ---------- + origin : numpy array + specifying the origin of the model + maximum : numpy array + specifying the maximum extent of the model + rescale : bool + whether to rescale the model to between 0/1 + + Examples + -------- + Demo data + + >>> from LoopStructural.datasets import load_claudius + >>> from LoopStructural import GeologicalModel + + >>> data, bb = load_claudius() + + >>> model = GeologicalModel(bb[:,0],bb[:,1] + >>> model.set_model_data(data) + >>> model.create_and_add_foliation('strati') + + >>> y = np.linspace(model.bounding_box[0, 1], model.bounding_box[1, 1], + nsteps[1]) + >>> z = np.linspace(model.bounding_box[1, 2], model.bounding_box[0, 2], + nsteps[2]) + >>> xx, yy, zz = np.meshgrid(x, y, z, indexing='ij') + >>> xyz = np.array([xx.flatten(), yy.flatten(), zz.flatten()]).T + >>> model.evaluate_feature_value('strati',xyz,scale=False) + + + """ + if logfile: + self.logfile = logfile + log_to_file(logfile,loglevel) + + logger.info('Initialising geological model') + self.features = [] + self.feature_name_index = {} + self.data = None + self.nsteps = nsteps + self._str = 'Instance of LoopStructural.GeologicalModel \n' + self._str += '------------------------------------------ \n' + # we want to rescale the model area so that the maximum length is + # 1 + self.origin = np.array(origin).astype(float) + originstr = 'Model origin: {} {} {}'.format(self.origin[0],self.origin[1],self.origin[2]) + logger.info(originstr) + self._str+=originstr+'\n' + self.maximum = np.array(maximum).astype(float) + maximumstr = 'Model maximum: {} {} {}'.format(self.maximum[0],self.maximum[1],self.maximum[2]) + logger.info(maximumstr) + self._str+=maximumstr+'\n' + + lengths = self.maximum - self.origin + self.scale_factor = 1. + self.bounding_box = np.zeros((2, 3)) + self.bounding_box[1, :] = self.maximum - self.origin + self.bounding_box[1, :] = self.maximum - self.origin + if rescale: + self.scale_factor = np.max(lengths) + logger.info('Rescaling model using scale factor {}'.format(self.scale_factor)) + self._str+='Model rescale factor: {} \n'.format(self.scale_factor) + self._str+='The model contains {} GeologicalFeatures \n'.format(len(self.features)) + self._str+='' + self._str += '------------------------------------------ \n' + self._str += '' + self.bounding_box /= self.scale_factor + self.support = {} + self.reuse_supports = reuse_supports + if self.reuse_supports: + logger.warning("Supports are shared between geological features \n" + "this may cause unexpected behaviour and should only\n" + "be use by advanced users") + logger.info('Reusing interpolation supports: {}'.format(self.reuse_supports)) + self.stratigraphic_column = None + self.parameters = {'features': [], 'model': {'bounding_box': self.origin.tolist() + self.maximum.tolist(), + 'rescale': rescale, + 'nsteps': nsteps, + 'reuse_supports': reuse_supports}} + + def __str__(self): + return self._str + + def _ipython_key_completions_(self): + return self.feature_name_index.keys() + + @classmethod + def from_map2loop_directory(cls, m2l_directory,**kwargs): + """Alternate constructor for a geological model using m2l output + + Uses the information saved in the map2loop files to build a geological model. + You can specify kwargs for building foliation using foliation_params and for + faults using fault_params. faults is a flag that allows for the faults to be skipped. + + Parameters + ---------- + m2l_directory : string + path to map2loop directory + + Returns + ------- + (GeologicalModel, dict) + the created geological model and a dictionary of the map2loop data + """ + from LoopStructural.utils import build_model, process_map2loop + logger.info('LoopStructural model initialised from m2l directory: {}'.format(m2l_directory)) + m2lflags = kwargs.pop('m2lflags',{}) + m2l_data = process_map2loop(m2l_directory,m2lflags) + return build_model(m2l_data,**kwargs), m2l_data + + @classmethod + def from_file(cls, file): + """Load a geological model from file + + Parameters + ---------- + file : string + path to the file + + Returns + ------- + GeologicalModel + the geological model object + """ + try: + import dill as pickle + except ImportError: + logger.error("Cannot import from file, dill not installed") + return None + model = pickle.load(open(file,'rb')) + if type(model) == GeologicalModel: + logger.info('GeologicalModel initialised from file') + return model + else: + logger.error('{} does not contain a geological model'.format(file)) + return None + + def __getitem__(self, feature_name): + """Accessor for feature in features using feature_name_index + + Parameters + ---------- + feature_name : string + name of the feature to return + """ + return self.get_feature_by_name(feature_name) + + def feature_names(self): + return self.feature_name_index.keys() + + def fault_names(self): + pass + + def check_inialisation(self): + if self.data is None: + logger.error("Data not associated with GeologicalModel. Run set_data") + return False + + def to_file(self, file): + """Save a model to a pickle file requires dill + + Parameters + ---------- + file : string + path to file location + """ + try: + import dill as pickle + except ImportError: + logger.error("Cannot write to file, dill not installed \n" + "pip install dill") + return + try: + logger.info('Writing GeologicalModel to: {}'.format(file)) + pickle.dump(self,open(file,'wb')) + except pickle.PicklingError: + logger.error('Error saving file') + + def _add_feature(self, feature): + """ + Add a feature to the model stack + + Parameters + ---------- + feature : GeologicalFeature + the geological feature to add + + """ + + if feature.name in self.feature_name_index: + logger.info("Feature %s already exists at %i, overwriting" % + (feature.name, self.feature_name_index[feature.name])) + self.features[self.feature_name_index[feature.name]] = feature + else: + self._str += 'GeologicalFeature: {} of type - {} \n'.format(feature.name,feature.type) + self.features.append(feature) + self.feature_name_index[feature.name] = len(self.features) - 1 + logger.info("Adding %s to model at location %i" % ( + feature.name, len(self.features))) + self._add_domain_fault_above(feature) + self._add_unconformity_above(feature) + feature.set_model(self) + + def data_for_feature(self,feature_name): + return self.data.loc[self.data['feature_name'] == feature_name,:] + + def set_model_data(self, data): + """ + Set the data array for the model + + Parameters + ---------- + data : pandas data frame + with column headers corresponding to the + type, X, Y, Z, nx, ny, nz, val, strike, dip, dip_dir, plunge, + plunge_dir, azimuth + + Returns + ------- + Note + ---- + Type can be any unique identifier for the feature the data point + 'eg' 'S0', 'S2', 'F1_axis' + it is then used by the create functions to get the correct data + """ + if type(data) != pd.DataFrame: + logger.warning( + "Data is not a pandas data frame, trying to read data frame " + "from csv") + try: + data = pd.read_csv(data) + except: + logger.error("Could not load pandas data frame from data") + logger.info('Adding data to GeologicalModel with {} data points'.format(len(data))) + self.data = data.copy() + self.data['X'] -= self.origin[0] + self.data['Y'] -= self.origin[1] + self.data['Z'] -= self.origin[2] + self.data['X'] /= self.scale_factor + self.data['Y'] /= self.scale_factor + self.data['Z'] /= self.scale_factor + if 'type' in self.data: + logger.warning("'type' is depreciated replace with 'feature_name' \n") + self.data.rename(columns={'type':'feature_name'},inplace=True) + for h in all_heading(): + if h not in self.data: + self.data[h] = np.nan + if h == 'w': + self.data[h] = 1. + if h == 'coord': + self.data[h] = 0 + + if 'strike' in self.data and 'dip' in self.data: + logger.info('Converting strike and dip to vectors') + mask = np.all(~np.isnan(self.data.loc[:, ['strike', 'dip']]), + axis=1) + self.data.loc[mask, gradient_vec_names()] = strike_dip_vector( + self.data.loc[mask, 'strike'], self.data.loc[mask, 'dip']) + self.data.drop(['strike', 'dip'], axis=1, inplace=True) + # self.data.loc + # if 'nx' in self.data and 'ny' in self.data and 'nz' in self.data: + # mask = np.all(~np.isnan(self.data.loc[:, ['nx', 'ny','nz']]), + # axis=1) + # self.data.loc[mask,['nx', 'ny','nz']] /= self.scale_factor + + def set_stratigraphic_column(self, stratigraphic_column,cmap='tab20'): + """ + Adds a stratigraphic column to the model + + Parameters + ---------- + stratigraphic_column : dictionary + cmap : matplotlib.cmap + Returns + ------- + + Notes + ----- + stratigraphic_column is a nested dictionary with the format + {'group': + {'series1': + {'min':0., 'max':10.,'id':0,'colour':} + } + } + + """ + # if the colour for a unit hasn't been specified we can just sample from + # a colour map e.g. tab20 + logger.info('Adding stratigraphic column to model') + random_colour = True + n_units=0 + for g in stratigraphic_column.keys(): + for u in stratigraphic_column[g].keys(): + if 'colour' in stratigraphic_column[g][u]: + random_colour = False + break + n_units+=1 + if random_colour: + import matplotlib.cm as cm + cmap = cm.get_cmap(cmap,n_units) + cmap_colours = cmap.colors + ci = 0 + for g in stratigraphic_column.keys(): + for u in stratigraphic_column[g].keys(): + stratigraphic_column[g][u]['colour'] = cmap_colours[ci,:] + + self.stratigraphic_column = stratigraphic_column + + def get_interpolator(self, interpolatortype='PLI', nelements=1e5, + buffer=0.2, element_volume = None, **kwargs): + """ + Returns an interpolator given the arguments, also constructs a + support for a discrete interpolator + + Parameters + ---------- + interpolatortype : string + define the interpolator type + nelements : int + number of elements in the interpolator + buffer : double or numpy array 3x1 + value(s) between 0,1 specifying the buffer around the bounding box + data_bb : bool + whether to use the model boundary or the boundary around + kwargs : no kwargs used, this just catches any additional arguments + + Returns + ------- + """ + # get an interpolator for + interpolator = None + bb = np.copy(self.bounding_box) + # add a buffer to the interpolation domain, this is necessary for + # faults but also generally a good + # idea to avoid boundary problems + # buffer = bb[1, :] + buffer = (bb[1,:]-bb[0,:])*buffer + bb[0, :] -= buffer # *(bb[1,:]-bb[0,:]) + bb[1, :] += buffer # *(bb[1,:]-bb[0,:]) + box_vol = (bb[1, 0]-bb[0, 0]) * (bb[1, 1]-bb[0, 1]) * (bb[1, 2]-bb[0, 2]) + if interpolatortype == "PLI": + if element_volume is None: + nelements /= 5 + element_volume = box_vol / nelements + # calculate the step vector of a regular cube + step_vector = np.zeros(3) + step_vector[:] = element_volume ** (1. / 3.) + # step_vector /= np.array([1,1,2]) + # number of steps is the length of the box / step vector + nsteps = np.ceil((bb[1, :] - bb[0, :]) / step_vector).astype(int) + # create a structured grid using the origin and number of steps + if self.reuse_supports: + mesh_id = 'mesh_{}'.format(nelements) + mesh = self.support.get(mesh_id, + TetMesh(origin=bb[0, :], nsteps=nsteps, + step_vector=step_vector)) + if mesh_id not in self.support: + self.support[mesh_id] = mesh + else: + mesh = TetMesh(origin=bb[0, :], nsteps=nsteps, step_vector=step_vector) + logger.info("Creating regular tetrahedron mesh with %i elements \n" + "for modelling using PLI" % (mesh.ntetra)) + + return PLI(mesh) + + if interpolatortype == 'FDI': + + # find the volume of one element + if element_volume is None: + element_volume = box_vol / nelements + # calculate the step vector of a regular cube + step_vector = np.zeros(3) + step_vector[:] = element_volume ** (1. / 3.) + # number of steps is the length of the box / step vector + nsteps = np.ceil((bb[1, :] - bb[0, :]) / step_vector).astype(int) + if np.any(np.less(nsteps, 3)): + logger.error("Cannot create interpolator: number of steps is too small") + return None + # create a structured grid using the origin and number of steps + if self.reuse_supports: + grid_id = 'grid_{}'.format(nelements) + grid = self.support.get(grid_id, StructuredGrid(origin=bb[0, :], + nsteps=nsteps, + step_vector=step_vector)) + if grid_id not in self.support: + self.support[grid_id] = grid + else: + grid = StructuredGrid(origin=bb[0, :], nsteps=nsteps,step_vector=step_vector) + logger.info("Creating regular grid with %i elements \n" + "for modelling using FDI" % grid.n_elements) + return FDI(grid) + + if interpolatortype == "DFI": # "fold" in kwargs: + if element_volume is None: + nelements /= 5 + element_volume = box_vol / nelements + # calculate the step vector of a regular cube + step_vector = np.zeros(3) + step_vector[:] = element_volume ** (1. / 3.) + # number of steps is the length of the box / step vector + nsteps = np.ceil((bb[1, :] - bb[0, :]) / step_vector).astype(int) + # create a structured grid using the origin and number of steps + mesh = kwargs.get('mesh', TetMesh(origin=bb[0, :], nsteps=nsteps, + step_vector=step_vector)) + logger.info("Creating regular tetrahedron mesh with %i elements \n" + "for modelling using DFI" % mesh.ntetra) + return DFI(mesh, kwargs['fold']) + if interpolatortype == 'Surfe' or interpolatortype == 'surfe' and \ + surfe: + method = kwargs.get('method', 'single_surface') + logger.info("Using surfe interpolator") + return Surfe(method) + logger.warning("No interpolator") + return interpolator + + def create_and_add_foliation(self, series_surface_data, **kwargs): + """ + Parameters + ---------- + series_surface_data : string + corresponding to the feature_name in the data + kwargs + + Returns + ------- + feature : GeologicalFeature + the created geological feature + """ + if self.check_inialisation() == False: + return False + interpolator = self.get_interpolator(**kwargs) + series_builder = GeologicalFeatureInterpolator(interpolator, + name=series_surface_data, + **kwargs) + # add data + series_data = self.data[self.data['feature_name'] == series_surface_data] + if series_data.shape[0] == 0: + logger.warning("No data for %s, skipping" % series_surface_data) + return + series_builder.add_data_from_data_frame(series_data) + self._add_faults(series_builder) + + # build feature + series_feature = series_builder.build(**kwargs) + series_feature.type = 'series' + # see if any unconformities are above this feature if so add region + # self._add_unconformity_above(series_feature)self._add_feature(series_feature) + self._add_feature(series_feature) + return series_feature + + + def _add_unconformity_above(self, feature): + """ + + Adds a region to the feature to prevent the value from being + interpolated where the unconformities exists above e.g. + if there is another feature above and the unconformity is at 0 + then the features added below (after) will only be visible where the + uncomformity is <0 + + Parameters + ---------- + feature - GeologicalFeature + + Returns + ------- + + """ + for f in reversed(self.features): + if f.type == 'unconformity': + feature.add_region(lambda pos: f.evaluate(pos)) + break + + def _add_unconformity_below(self, feature): + """ + Adds a region to the features that represents the + unconformity so it is not evaluated below the unconformity + + Parameters + ---------- + feature + + Returns + ------- + + """ + for f in self.features: + if f.type == 'series' and feature.feature.name != f.name: + f.add_region(lambda pos: ~feature.evaluate(pos)) + + def add_unconformity(self, feature, value): + """ + Use an existing feature to add an unconformity to the model. + + Parameters + ---------- + feature : GeologicalFeature + existing geological feature + value : float + scalar value of isosurface that represents + + Returns + ------- + unconformity : GeologicalFeature + unconformity feature + + """ + self.parameters['features'].append({'feature_type': 'unconformity', 'feature': feature, 'value': value}) + uc_feature = UnconformityFeature(feature, value) + + # for f in self.features: + # f.add_region(lambda pos: uc_feature.evaluate(pos)) + + # see if any unconformities are above this feature if so add region + # self._add_unconformity_above(uc_feature) + # self._add_unconformity_below(feature)#, uc_feature) + self._add_feature(uc_feature) + + + return uc_feature + + def add_onlap_unconformity(self, feature, value): + """ + Use an existing feature to add an unconformity to the model. + + Parameters + ---------- + feature : GeologicalFeature + existing geological feature + value : float + scalar value of isosurface that represents + + Returns + ------- + unconformity_feature : GeologicalFeature + the created unconformity + + """ + self.parameters['features'].append({'feature_type': 'onlap', 'feature': feature, 'value': value}) + + uc_feature = UnconformityFeature(feature, value) + + # for f in self.features: + # f.add_region(lambda pos: uc_feature.evaluate(pos)) + + # see if any unconformities are above this feature if so add region + # self._add_unconformity_above(uc_feature) + self._add_unconformity_below(uc_feature) # , uc_feature) + self._add_feature(uc_feature) + + + return uc_feature + + def create_and_add_fault(self, fault_surface_data, displacement, renormalise=True, **kwargs): + """ + Parameters + ---------- + fault_surface_data : string + name of the fault surface data in the dataframe + displacement : displacement magnitude + kwargs : additional kwargs for Fault and interpolators + + Returns + ------- + fault : FaultSegment + created fault + """ + self.parameters['features'].append( + {'feature_type': 'fault', 'feature_name': fault_surface_data, 'displacement': displacement, **kwargs}) + + displacement_scaled = displacement / self.scale_factor + # create fault frame + interpolator = self.get_interpolator(**kwargs) + fault_frame_builder = StructuralFrameBuilder(interpolator, + name=fault_surface_data, + **kwargs) + # add data + fault_frame_data = self.data[ + self.data['feature_name'] == fault_surface_data].copy() + if 'coord' not in fault_frame_data: + fault_frame_data['coord'] = 0 + vals = fault_frame_data['val'] + fault_frame_builder.add_data_from_data_frame(fault_frame_data) + # if there is no fault slip data then we could find the strike of + # the fault and build + # the second coordinate + # if we add a region to the fault then the fault operator doesn't + # work but for visualisation + # we want to add a region! + # check if this fault overprint any existing faults exist in the stack + + + fault_frame = fault_frame_builder.build(**kwargs) + if 'abut' in kwargs: + fault_frame[0].add_region(lambda pos: kwargs['abut'].evaluate(pos)) + + fault = FaultSegment(fault_frame, displacement=displacement_scaled, + **kwargs) + for f in reversed(self.features): + if f.type == 'unconformity': + fault.add_region(lambda pos: f.evaluate_value(pos) <= 0) + break + if displacement == 0: + fault.type = 'fault_inactive' + self._add_feature(fault) + + + return fault + + def rescale(self, points, inplace=True): + """ + Convert from model scale to real world scale - in the future this + should also do transformations? + + Parameters + ---------- + points : np.array((N,3),dtype=double) + inplace : boolean + whether to return a modified copy or modify the original array + + Returns + ------- + points : np.array((N,3),dtype=double) + + """ + if inplace == False: + points = points.copy() + points *= self.scale_factor + points += self.origin + return points + + def scale(self, points, inplace=True): + """ Take points in UTM coordinates and reproject + into scaled model space + + Parameters + ---------- + points : np.array((N,3),dtype=float) + points to + inplace : bool, optional default = True + whether to copy the points array or update the passed array + Returns + ------- + points : np.array((N,3),dtype=double) + + """ + if inplace==False: + points = points.copy() + + points[:, :] -= self.origin + points /= self.scale_factor + return points + + + def regular_grid(self, nsteps=(50, 50, 25), shuffle = True, rescale=False): + """ + Return a regular grid within the model bounding box + + Parameters + ---------- + nsteps : tuple + number of cells in x,y,z + + Returns + ------- + xyz : np.array((N,3),dtype=float) + locations of points in regular grid + """ + x = np.linspace(self.bounding_box[0, 0], self.bounding_box[1, 0], + nsteps[0]) + y = np.linspace(self.bounding_box[0, 1], self.bounding_box[1, 1], + nsteps[1]) + z = np.linspace(self.bounding_box[1, 2], self.bounding_box[0, 2], + nsteps[2]) + xx, yy, zz = np.meshgrid(x, y, z, indexing='ij') + locs = np.array([xx.flatten(), yy.flatten(), zz.flatten()]).T + if shuffle: + logger.info("Shuffling points") + np.random.shuffle(locs) + if rescale: + locs = self.rescale(locs) + return locs + + def evaluate_model(self, xyz, scale=True): + """Evaluate the stratigraphic id at each location + + + Parameters + ---------- + xyz : np.array((N,3),dtype=float) + locations + scale : bool + whether to rescale the xyz before evaluating model + + Returns + ------- + stratigraphic_id : np.array(N,dtype=int) + the stratigraphic index for locations + + Examples + -------- + Evaluate on a voxet + + >>> x = np.linspace(model.bounding_box[0, 0], model.bounding_box[1, 0], + nsteps[0]) + >>> y = np.linspace(model.bounding_box[0, 1], model.bounding_box[1, 1], + nsteps[1]) + >>> z = np.linspace(model.bounding_box[1, 2], model.bounding_box[0, 2], + nsteps[2]) + >>> xx, yy, zz = np.meshgrid(x, y, z, indexing='ij') + >>> xyz = np.array([xx.flatten(), yy.flatten(), zz.flatten()]).T + >>> model.evaluate_model(xyz) + + Evaluate on points defined by regular grid function + + >>> model.evaluate_model(model.regular_grid()) + + + Evaluate on a map + + >>> x = np.linspace(self.bounding_box[0, 0], self.bounding_box[1, 0], + nsteps[0]) + >>> y = np.linspace(self.bounding_box[0, 1], self.bounding_box[1, 1], + nsteps[1]) + >>> xx, yy = np.meshgrid(x, y, indexing='ij') + >>> zz = np.zeros_like(yy) + >>> xyz = np.array([xx.flatten(), yy.flatten(), zz.flatten()]).T + >>> model.evaluate_model(xyz) + + """ + if scale: + xyz = self.scale(xyz,inplace=False) + strat_id = np.zeros(xyz.shape[0],dtype=int) + for group in self.stratigraphic_column.keys(): + if group == 'faults': + continue + feature_id = self.feature_name_index.get(group, -1) + if feature_id >= 0: + feature = self.features[feature_id] + vals = feature.evaluate_value(xyz) + for series in self.stratigraphic_column[group].values(): + strat_id[np.logical_and(vals < series.get('max',feature.max()), vals > series.get('min',feature.min()))] = series['id'] + if feature_id == -1: + logger.error('Model does not contain {}'.format(group)) + return strat_id + + def evaluate_fault_displacements(self,points,scale=True): + """Evaluate the fault displacement magnitude at each location + + + Parameters + ---------- + xyz : np.array((N,3),dtype=float) + locations + scale : bool + whether to rescale the xyz before evaluating model + + Returns + ------- + fault_displacement : np.array(N,dtype=float) + the fault displacement magnitude + """ + if scale: + points = self.scale(points,inplace=False) + vals = np.zeros(points.shape[0]) + for f in self.features: + if f.type == 'fault': + disp = f.displacementfeature.evaluate_value(points) + vals[~np.isnan(disp)] += disp[~np.isnan(disp)] + return vals*-self.scale_factor # convert from restoration magnutude to displacement + + diff --git a/LoopStructural/modelling/features/geological_feature_builder.py b/LoopStructural/modelling/features/geological_feature_builder.py index 018929b3f..c351dca37 100644 --- a/LoopStructural/modelling/features/geological_feature_builder.py +++ b/LoopStructural/modelling/features/geological_feature_builder.py @@ -33,9 +33,9 @@ def __init__(self, interpolator, name='Feature', region=None, **kwargs): defining whether the location (xyz) should be included in the kwargs - name of the feature, region to interpolate the feature """ - self.interpolator = interpolator - self.name = name - self.interpolator.set_property_name(self.name) + self._interpolator = interpolator + self._name = name + self._interpolator.set_property_name(self.name) # everywhere region is just a lambda that returns true for all locations if region is None: self.region = lambda pos: np.ones(pos.shape[0], dtype=bool) @@ -47,6 +47,14 @@ def __init__(self, interpolator, name='Feature', region=None, **kwargs): self.faults = [] self.data_added = False self.interpolator.set_region(region=self.region) + self._feature = None + self.up_to_date = False + + @property + def feature(self): + if self.up_to_date == False: + self.update() + return self._feature def update(self): pass @@ -64,6 +72,7 @@ def add_fault(self, fault): ------- """ + self.up_to_date = False self.faults.append(fault) def add_data_from_data_frame(self, data_frame): @@ -104,6 +113,7 @@ def add_orthogonal_feature(self, feature, w=1., region=None,step=1,B=0): The constraint can be applied to a random subset of the tetrahedral elements in the mesh in theory this shu """ + self.up_to_date = False vector = feature.evaluate_gradient(self.interpolator.support.barycentre()) vector /= np.linalg.norm(vector,axis=1)[:,None] element_idx = np.arange(self.interpolator.support.n_elements) @@ -208,6 +218,7 @@ def add_data_to_interpolator(self, constrained=False, force_constrained=False, * self.interpolator.set_interface_constraints(interface_data) self.data_added = True + self.up_to_date = False def get_value_constraints(self): """ @@ -346,10 +357,11 @@ def build(self, fold=None, fold_weights={}, data_region=None, **kwargs): self.interpolator.setup_interpolator(**kwargs) self.interpolator.solve_system(**kwargs) - return GeologicalFeature(self.name, + self._feature = GeologicalFeature(self.name, self.interpolator, builder=self, data=self.data, region=self.region, faults=self.faults, fold = fold ) + return self._feature From 0ff1eb41c2573c086f84dc9fbd0fc9e66f9b8fe8 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 22 Jan 2021 15:18:07 +1100 Subject: [PATCH 02/29] (DEV) updated setup --- setup.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/setup.py b/setup.py index c210a90af..8f3edb9bc 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,24 @@ #setup cython code -from setuptools import setup, find_packages -from Cython.Build import cythonize +import sys +try: + from setuptools import setup, find_packages +except: + raise RuntimeError("Cannot import setuptools \n"\ + "python -m pip install setuptools") + sys.exit(1) + +try: + from Cython.Build import cythonize +except: + raise RuntimeError("Cannot import cython \n"\ + "python -m pip install cython") + sys.exit(1) +try: + import numpy +except: + raise RuntimeError("Cannot import numpy \n"\ + "python -m pip install numpy") + sys.exit(1) import numpy import os import codecs @@ -20,14 +38,14 @@ def get_version(rel_path): setup( name="LoopStructural", install_requires=[ - # 'Cython', - # 'numpy', - # 'pandas', - # 'scipy', - # 'matplotlib', - # # 'lavavu', - # 'scikit-image', - # 'scikit-learn' + 'Cython', + 'numpy', + 'pandas', + 'scipy', + 'matplotlib', + # 'lavavu', + 'scikit-image', + 'scikit-learn' ], version=get_version("LoopStructural/__init__.py"), packages=find_packages(), From 2b6b4e876a6def32ee315d09781e811b3390890c Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 22 Jan 2021 15:20:10 +1100 Subject: [PATCH 03/29] (DEV) testing ideas for how to implement builder --- .../modelling/core/geological_model_graph.py | 12 ++++------- .../features/geological_feature_builder.py | 20 +++++++++++++------ dev/run_model.py | 8 ++++++++ 3 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 dev/run_model.py diff --git a/LoopStructural/modelling/core/geological_model_graph.py b/LoopStructural/modelling/core/geological_model_graph.py index 959e627d5..f22ea1c09 100644 --- a/LoopStructural/modelling/core/geological_model_graph.py +++ b/LoopStructural/modelling/core/geological_model_graph.py @@ -529,15 +529,11 @@ def create_and_add_foliation(self, series_surface_data, **kwargs): logger.warning("No data for %s, skipping" % series_surface_data) return series_builder.add_data_from_data_frame(series_data) - self._add_faults(series_builder) + # self._add_faults(series_builder) - # build feature - series_feature = series_builder.build(**kwargs) - series_feature.type = 'series' - # see if any unconformities are above this feature if so add region - # self._add_unconformity_above(series_feature)self._add_feature(series_feature) - self._add_feature(series_feature) - return series_feature + + self.features.append(series_builder.feature) + return series_builder def _add_unconformity_above(self, feature): diff --git a/LoopStructural/modelling/features/geological_feature_builder.py b/LoopStructural/modelling/features/geological_feature_builder.py index c351dca37..f517d9ae6 100644 --- a/LoopStructural/modelling/features/geological_feature_builder.py +++ b/LoopStructural/modelling/features/geological_feature_builder.py @@ -35,7 +35,7 @@ def __init__(self, interpolator, name='Feature', region=None, **kwargs): """ self._interpolator = interpolator self._name = name - self._interpolator.set_property_name(self.name) + self._interpolator.set_property_name(self._name) # everywhere region is just a lambda that returns true for all locations if region is None: self.region = lambda pos: np.ones(pos.shape[0], dtype=bool) @@ -46,18 +46,26 @@ def __init__(self, interpolator, name='Feature', region=None, **kwargs): self.data = pd.DataFrame(columns=header) self.faults = [] self.data_added = False - self.interpolator.set_region(region=self.region) + self._interpolator.set_region(region=self.region) self._feature = None self.up_to_date = False - + self._build_arguments = {} + @property def feature(self): - if self.up_to_date == False: - self.update() return self._feature + @property + def build_arguments(self): + return self._build_arguments + + @build_arguments.setter + def build_arguments(self, build_arguments): + self._build_arguments = build_arguments + def update(self): - pass + self.build(self.build_arguments) + def add_fault(self, fault): """ diff --git a/dev/run_model.py b/dev/run_model.py new file mode 100644 index 000000000..f995a3e67 --- /dev/null +++ b/dev/run_model.py @@ -0,0 +1,8 @@ +from LoopStructural.modelling.core.geological_model_graph import GeologicalModel +from LoopStructural.datasets import load_claudius + +data, bb = load_claudius() + +model = GeologicalModel(bb[0,:],bb[1,:]) +model.set_model_data(data) +model.create_and_add_foliation('strati') \ No newline at end of file From c7fcc2af9c43965eab85414d14fcf61dad81af40 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 22 Jan 2021 15:55:52 +1100 Subject: [PATCH 04/29] (DEV) adding class for regions --- LoopStructural/utils/__init__.py | 3 ++- LoopStructural/utils/regions.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 LoopStructural/utils/regions.py diff --git a/LoopStructural/utils/__init__.py b/LoopStructural/utils/__init__.py index a49ffec83..7bb8b994b 100644 --- a/LoopStructural/utils/__init__.py +++ b/LoopStructural/utils/__init__.py @@ -14,4 +14,5 @@ from .logging import getLogger, log_to_file, log_to_console from .map2loop import process_map2loop, build_model from .helper import get_data_axis_aligned_bounding_box, get_data_bounding_box, get_data_bounding_box_map -from .helper import get_dip_vector,get_strike_vector, get_vectors \ No newline at end of file +from .helper import get_dip_vector,get_strike_vector, get_vectors +from .regions import RegionEverywhere \ No newline at end of file diff --git a/LoopStructural/utils/regions.py b/LoopStructural/utils/regions.py new file mode 100644 index 000000000..f2a7ab229 --- /dev/null +++ b/LoopStructural/utils/regions.py @@ -0,0 +1,11 @@ +import numpy as np + +class RegionEverywhere: + def __call__(self,xyz): + return np.ones(xyz.shape[0],dtype='int64') + +class RegionFunction: + def __init__(self,function): + self.function = function + def __call__(self,xyz): + return self.function(xyz) \ No newline at end of file From e6841f1226da54c0e93a33e20bc723fa37b9a44c Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 22 Jan 2021 15:56:20 +1100 Subject: [PATCH 05/29] (DEV) test can add feature to model without interpolating and then interpolate when evaluating model --- .../modelling/core/geological_model_graph.py | 2 +- .../modelling/features/geological_feature.py | 48 ++----------------- .../features/geological_feature_builder.py | 44 +++++++++++------ dev/run_model.py | 3 +- 4 files changed, 38 insertions(+), 59 deletions(-) diff --git a/LoopStructural/modelling/core/geological_model_graph.py b/LoopStructural/modelling/core/geological_model_graph.py index f22ea1c09..e9182b860 100644 --- a/LoopStructural/modelling/core/geological_model_graph.py +++ b/LoopStructural/modelling/core/geological_model_graph.py @@ -533,7 +533,7 @@ def create_and_add_foliation(self, series_surface_data, **kwargs): self.features.append(series_builder.feature) - return series_builder + return series_builder.feature def _add_unconformity_above(self, feature): diff --git a/LoopStructural/modelling/features/geological_feature.py b/LoopStructural/modelling/features/geological_feature.py index 0018191b1..d4990a468 100644 --- a/LoopStructural/modelling/features/geological_feature.py +++ b/LoopStructural/modelling/features/geological_feature.py @@ -48,7 +48,6 @@ def __init__(self, name, interpolator, builder=None, data=None, region=None, typ self.name = name self.interpolator = interpolator self.ndim = 1 - self.data = data self.builder = builder self.region = region self.regions = [] @@ -105,20 +104,6 @@ def add_region(self, region): """ self.regions.append(region) - def set_builder(self, builder): - """ - - Parameters - ---------- - builder : GeologicalFeatureInterpolator - the builder associated with this feature - - Returns - ------- - - """ - self.builder = builder - def evaluate_value(self, evaluation_points): """ Evaluate the scalar field value of the geological feature at the locations @@ -135,7 +120,7 @@ def evaluate_value(self, evaluation_points): numpy array containing evaluated values """ - + self.builder.up_to_date() # check if the points are within the display region v = np.zeros(evaluation_points.shape[0]) v[:] = np.nan @@ -163,6 +148,7 @@ def evaluate_gradient(self, evaluation_points): ------- """ + self.up_to_date() v = np.zeros(evaluation_points.shape) v[:] = np.nan mask = np.zeros(evaluation_points.shape[0]).astype(bool) @@ -187,6 +173,7 @@ def evaluate_gradient_misfit(self): misfit : np.array(N,dtype=double) dot product between interpolated gradient and constraints """ + self.up_to_date() grad = self.interpolator.get_gradient_constraints() norm = self.interpolator.get_norm_constraints() @@ -211,6 +198,8 @@ def evaluate_value_misfit(self): misfit : np.array(N,dtype=double) difference between interpolated scalar field and value constraints """ + self.up_to_date() + locations = self.interpolator.get_value_constraints() diff = np.abs(locations[:, 3] - self.evaluate_value(locations[:, :3])) diff/=(self.max()-self.min()) @@ -257,31 +246,4 @@ def max(self): return np.nanmax( self.evaluate_value(self.model.regular_grid((10, 10, 10)))) - def update(self): - """ - Calculate average of the support values - - Returns - ------- - - """ - # re-run the interpolator and update the support. - # this is a bit clumsy and not abstract, i think - # if evaluating the property doesn't require the dictionary on - # the nodes and actually just uses the interpolator values this - # would be - # much better. - self.interpolator.up_to_date = False - self.interpolator.update() - - def get_interpolator(self): - """ - Get the interpolator used to build this feature - - Returns - ------- - interpolator : GeologicalInterpolator - """ - return self.interpolator - diff --git a/LoopStructural/modelling/features/geological_feature_builder.py b/LoopStructural/modelling/features/geological_feature_builder.py index f517d9ae6..f51eee526 100644 --- a/LoopStructural/modelling/features/geological_feature_builder.py +++ b/LoopStructural/modelling/features/geological_feature_builder.py @@ -15,6 +15,7 @@ from LoopStructural.modelling.features import GeologicalFeature from LoopStructural.utils.helper import get_data_bounding_box_map as get_data_bounding_box from LoopStructural.utils import get_data_axis_aligned_bounding_box +from LoopStructural.utils import RegionEverywhere class GeologicalFeatureInterpolator: """[summary] @@ -38,7 +39,7 @@ def __init__(self, interpolator, name='Feature', region=None, **kwargs): self._interpolator.set_property_name(self._name) # everywhere region is just a lambda that returns true for all locations if region is None: - self.region = lambda pos: np.ones(pos.shape[0], dtype=bool) + self.region = RegionEverywhere() else: self.region = region header = xyz_names()+val_name()+gradient_vec_names()+\ @@ -48,9 +49,16 @@ def __init__(self, interpolator, name='Feature', region=None, **kwargs): self.data_added = False self._interpolator.set_region(region=self.region) self._feature = None - self.up_to_date = False + self._up_to_date = False self._build_arguments = {} - + self.fold = None + self._feature = GeologicalFeature(self._name, + self._interpolator, + builder=self, + region=self.region, + faults=self.faults, + fold = self.fold + ) @property def feature(self): return self._feature @@ -64,9 +72,23 @@ def build_arguments(self, build_arguments): self._build_arguments = build_arguments def update(self): - self.build(self.build_arguments) + self.build(**self.build_arguments) + @property + def name(self): + return self._name + @property + def interpolator(self): + return self._interpolator + + def up_to_date(self): + #has anything changed in the builder since we built the feature? if so update + if self._up_to_date == False: + self.update() + #check if the interpolator is up to date, if not solve + if self._interpolator.up_to_date == False: + self.update() + - def add_fault(self, fault): """ Add a fault to the geological feature builder @@ -121,7 +143,7 @@ def add_orthogonal_feature(self, feature, w=1., region=None,step=1,B=0): The constraint can be applied to a random subset of the tetrahedral elements in the mesh in theory this shu """ - self.up_to_date = False + self._up_to_date = False vector = feature.evaluate_gradient(self.interpolator.support.barycentre()) vector /= np.linalg.norm(vector,axis=1)[:,None] element_idx = np.arange(self.interpolator.support.n_elements) @@ -226,7 +248,7 @@ def add_data_to_interpolator(self, constrained=False, force_constrained=False, * self.interpolator.set_interface_constraints(interface_data) self.data_added = True - self.up_to_date = False + self._up_to_date = False def get_value_constraints(self): """ @@ -365,11 +387,5 @@ def build(self, fold=None, fold_weights={}, data_region=None, **kwargs): self.interpolator.setup_interpolator(**kwargs) self.interpolator.solve_system(**kwargs) - self._feature = GeologicalFeature(self.name, - self.interpolator, - builder=self, data=self.data, - region=self.region, - faults=self.faults, - fold = fold - ) + self._up_to_date = True return self._feature diff --git a/dev/run_model.py b/dev/run_model.py index f995a3e67..89535a3ea 100644 --- a/dev/run_model.py +++ b/dev/run_model.py @@ -5,4 +5,5 @@ model = GeologicalModel(bb[0,:],bb[1,:]) model.set_model_data(data) -model.create_and_add_foliation('strati') \ No newline at end of file +strati = model.create_and_add_foliation('strati') +strati.evaluate_value(model.regular_grid()) \ No newline at end of file From 50241c2e6c82e02d83233a2555ffc8b980276292 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Mon, 25 Jan 2021 10:15:03 +1100 Subject: [PATCH 06/29] (DEV) updating faults to evaluate on demand --- .../finite_difference_interpolator.py | 1 - .../modelling/core/geological_model_graph.py | 54 +++++++++++++------ .../modelling/features/geological_feature.py | 6 +-- .../features/geological_feature_builder.py | 39 ++++++++------ .../features/structural_frame_builder.py | 36 +++++-------- LoopStructural/utils/regions.py | 2 +- dev/run_model.py | 28 ++++++++-- 7 files changed, 101 insertions(+), 65 deletions(-) diff --git a/LoopStructural/interpolators/finite_difference_interpolator.py b/LoopStructural/interpolators/finite_difference_interpolator.py index b58735985..1c6b3dade 100644 --- a/LoopStructural/interpolators/finite_difference_interpolator.py +++ b/LoopStructural/interpolators/finite_difference_interpolator.py @@ -75,7 +75,6 @@ def _setup_interpolator(self, **kwargs): ------- """ - for key in kwargs: self.up_to_date = False if 'regularisation' in kwargs: diff --git a/LoopStructural/modelling/core/geological_model_graph.py b/LoopStructural/modelling/core/geological_model_graph.py index e9182b860..ccef7b9c3 100644 --- a/LoopStructural/modelling/core/geological_model_graph.py +++ b/LoopStructural/modelling/core/geological_model_graph.py @@ -5,6 +5,8 @@ import numpy as np import pandas as pd +import networkx as nx + from LoopStructural.datasets import normal_vector_headers from LoopStructural.interpolators.discrete_fold_interpolator import \ DiscreteFoldInterpolator as DFI @@ -164,6 +166,7 @@ def __init__(self, origin, maximum, rescale=True, nsteps=(40, 40, 40), "be use by advanced users") logger.info('Reusing interpolation supports: {}'.format(self.reuse_supports)) self.stratigraphic_column = None + self.feature_graph = nx.DiGraph() self.parameters = {'features': [], 'model': {'bounding_box': self.origin.tolist() + self.maximum.tolist(), 'rescale': rescale, 'nsteps': nsteps, @@ -288,10 +291,31 @@ def _add_feature(self, feature): self.feature_name_index[feature.name] = len(self.features) - 1 logger.info("Adding %s to model at location %i" % ( feature.name, len(self.features))) - self._add_domain_fault_above(feature) - self._add_unconformity_above(feature) + # self._add_domain_fault_above(feature) + # self._add_unconformity_above(feature) feature.set_model(self) - + + def _add_faults(self, feature_builder, features=None): + """Adds all existing faults to a geological feature builder + + Parameters + ---------- + feature_builder : GeologicalFeatureInterpolator/StructuralFrameBuilder + The feature buider to add the faults to + features : list, optional + A specific list of features rather than all features in the model + Returns + ------- + + """ + if features is None: + features = self.features + for f in reversed(features): + if f.type == 'fault': + feature_builder.add_fault(f) + # if f.type == 'unconformity': + # break + def data_for_feature(self,feature_name): return self.data.loc[self.data['feature_name'] == feature_name,:] @@ -529,10 +553,10 @@ def create_and_add_foliation(self, series_surface_data, **kwargs): logger.warning("No data for %s, skipping" % series_surface_data) return series_builder.add_data_from_data_frame(series_data) - # self._add_faults(series_builder) + self._add_faults(series_builder) - - self.features.append(series_builder.feature) + series_builder.build_arguments = kwargs + self._add_feature(series_builder.feature) return series_builder.feature @@ -675,22 +699,20 @@ def create_and_add_fault(self, fault_surface_data, displacement, renormalise=Tru # work but for visualisation # we want to add a region! # check if this fault overprint any existing faults exist in the stack - fault_frame = fault_frame_builder.build(**kwargs) - if 'abut' in kwargs: - fault_frame[0].add_region(lambda pos: kwargs['abut'].evaluate(pos)) + fault = FaultSegment(fault_frame, displacement=displacement_scaled, **kwargs) - for f in reversed(self.features): - if f.type == 'unconformity': - fault.add_region(lambda pos: f.evaluate_value(pos) <= 0) - break - if displacement == 0: - fault.type = 'fault_inactive' + # for f in reversed(self.features): + # if f.type == 'unconformity': + # fault.add_region(lambda pos: f.evaluate_value(pos) <= 0) + # break + # if displacement == 0: + # fault.type = 'fault_inactive' + # self._add_feature(fault) self._add_feature(fault) - return fault diff --git a/LoopStructural/modelling/features/geological_feature.py b/LoopStructural/modelling/features/geological_feature.py index d4990a468..160cc2545 100644 --- a/LoopStructural/modelling/features/geological_feature.py +++ b/LoopStructural/modelling/features/geological_feature.py @@ -148,7 +148,7 @@ def evaluate_gradient(self, evaluation_points): ------- """ - self.up_to_date() + self.builder.up_to_date() v = np.zeros(evaluation_points.shape) v[:] = np.nan mask = np.zeros(evaluation_points.shape[0]).astype(bool) @@ -173,7 +173,7 @@ def evaluate_gradient_misfit(self): misfit : np.array(N,dtype=double) dot product between interpolated gradient and constraints """ - self.up_to_date() + self.builder.up_to_date() grad = self.interpolator.get_gradient_constraints() norm = self.interpolator.get_norm_constraints() @@ -198,7 +198,7 @@ def evaluate_value_misfit(self): misfit : np.array(N,dtype=double) difference between interpolated scalar field and value constraints """ - self.up_to_date() + self.builder.up_to_date() locations = self.interpolator.get_value_constraints() diff = np.abs(locations[:, 3] - self.evaluate_value(locations[:, :3])) diff --git a/LoopStructural/modelling/features/geological_feature_builder.py b/LoopStructural/modelling/features/geological_feature_builder.py index f51eee526..2231ea6e8 100644 --- a/LoopStructural/modelling/features/geological_feature_builder.py +++ b/LoopStructural/modelling/features/geological_feature_builder.py @@ -59,6 +59,7 @@ def __init__(self, interpolator, name='Feature', region=None, **kwargs): faults=self.faults, fold = self.fold ) + self._orthogonal_features = {} @property def feature(self): return self._feature @@ -69,7 +70,9 @@ def build_arguments(self): @build_arguments.setter def build_arguments(self, build_arguments): - self._build_arguments = build_arguments + # self._build_arguments = {} + for k, i in build_arguments.items(): + self._build_arguments[k] = i def update(self): self.build(**self.build_arguments) @@ -102,7 +105,7 @@ def add_fault(self, fault): ------- """ - self.up_to_date = False + self._up_to_date = False self.faults.append(fault) def add_data_from_data_frame(self, data_frame): @@ -143,17 +146,9 @@ def add_orthogonal_feature(self, feature, w=1., region=None,step=1,B=0): The constraint can be applied to a random subset of the tetrahedral elements in the mesh in theory this shu """ + self._orthogonal_features[feature.name] = [feature,w,region,step,B] self._up_to_date = False - vector = feature.evaluate_gradient(self.interpolator.support.barycentre()) - vector /= np.linalg.norm(vector,axis=1)[:,None] - element_idx = np.arange(self.interpolator.support.n_elements) - np.random.shuffle(element_idx) - self.interpolator.add_gradient_orthogonal_constraint( - self.interpolator.support.barycentre()[element_idx[::step],:], - vector[element_idx[::step],:], - w=w, - B=B - ) + def add_data_to_interpolator(self, constrained=False, force_constrained=False, **kwargs): """ @@ -249,7 +244,20 @@ def add_data_to_interpolator(self, constrained=False, force_constrained=False, * self.data_added = True self._up_to_date = False - + + def install_gradient_constraint(self): + for g in self._orthogonal_features.values(): + feature,w,region,step,B = g + vector = feature.evaluate_gradient(self.interpolator.support.barycentre()) + vector /= np.linalg.norm(vector,axis=1)[:,None] + element_idx = np.arange(self.interpolator.support.n_elements) + np.random.shuffle(element_idx) + self.interpolator.add_gradient_orthogonal_constraint( + self.interpolator.support.barycentre()[element_idx[::step],:], + vector[element_idx[::step],:], + w=w, + B=B + ) def get_value_constraints(self): """ Get the value constraints for this geological feature @@ -352,8 +360,7 @@ def build(self, fold=None, fold_weights={}, data_region=None, **kwargs): """ - if not self.data_added: - self.add_data_to_interpolator(**kwargs) + self.add_data_to_interpolator(**kwargs) if data_region is not None: xyz = self.interpolator.get_data_locations() bb, region = get_data_bounding_box(xyz, data_region) @@ -384,7 +391,7 @@ def build(self, fold=None, fold_weights={}, data_region=None, **kwargs): if 'cgw' not in kwargs: # try adding very small cg kwargs['cgw'] = 0.0 - + self.interpolator.setup_interpolator(**kwargs) self.interpolator.solve_system(**kwargs) self._up_to_date = True diff --git a/LoopStructural/modelling/features/structural_frame_builder.py b/LoopStructural/modelling/features/structural_frame_builder.py index 1c2277896..11f139fa6 100644 --- a/LoopStructural/modelling/features/structural_frame_builder.py +++ b/LoopStructural/modelling/features/structural_frame_builder.py @@ -125,8 +125,10 @@ def build(self, w1=1., w2=1., w3=1., frame=StructuralFrame, **kwargs): fold = None if len(self.builders[0].data) > 0: logger.info("Building %s coordinate 0"%self.name) - gx_feature = self.builders[0].build(regularisation=regularisation[ - 0], **kwargs) + gx_feature = self.builders[0].feature + kwargs['regularisation']=regularisation[0] + self.builders[0].build_arguments = kwargs + # remove fold from kwargs fold = kwargs.pop('fold', None) @@ -135,9 +137,9 @@ def build(self, w1=1., w2=1., w3=1., frame=StructuralFrame, **kwargs): "Not enough constraints for structural frame coordinate 0, \n" "Add some more and try again.") # make sure that all of the coordinates are using the same region - if gx_feature is not None and gx_feature.get_interpolator().region_function is not None: - self.builders[1].interpolator.set_region(gx_feature.get_interpolator().region_function) - self.builders[2].interpolator.set_region(gx_feature.get_interpolator().region_function) + if gx_feature is not None and gx_feature.interpolator.region_function is not None: + self.builders[1].interpolator.set_region(gx_feature.interpolator.region_function) + self.builders[2].interpolator.set_region(gx_feature.interpolator.region_function) if 'data_region' in kwargs: kwargs.pop('data_region') if 'region' in kwargs: @@ -152,7 +154,9 @@ def build(self, w1=1., w2=1., w3=1., frame=StructuralFrame, **kwargs): # w=gyxgz) if gx_feature is not None and gxxgz>0: self.builders[2].add_orthogonal_feature(gx_feature, gxxgz,step=step) - gz_feature = self.builders[2].build(regularisation=regularisation[2], **kwargs) + gz_feature = self.builders[2].feature + kwargs['regularisation'] = regularisation[2] + self.builders[2].build_arguments = kwargs if len(self.builders[1].data) > 0: logger.info("Building %s coordinate 1"%self.name) @@ -160,23 +164,9 @@ def build(self, w1=1., w2=1., w3=1., frame=StructuralFrame, **kwargs): self.builders[1].add_orthogonal_feature(gx_feature, gxxgy,step=step) if gz_feature is not None and gyxgz>0: self.builders[1].add_orthogonal_feature(gz_feature, gyxgz,step=step) - gy_const_norm = kwargs.get('gy_const_norm',0.) - - ## bit of an ugly hack, adding in norm constraints for the norm we are forcing - # if gz_feature is not None: - # tmp = CrossProductGeologicalFeature('tmp',gx_feature,gz_feature) - # self.builders[1].add_orthogonal_feature(tmp,10.,step=step,B=1) - # # gy_feature.value_feature = fold.fold frame[0] - # # vector = feature.evaluate_gradient(self.builders[1].interpolator.support.barycentre()) - # # vector /= np.linalg.norm(vector,axis=1)[:,None] - # # element_idx = np.arange(self.builders[1].interpolator.support.n_elements) - # # np.random.shuffle(element_idx) - # # norm_pts = np.hstack([self.builders[1].interpolator.support.barycentre()[element_idx[::step],:],vector[element_idx[::step],:],np.ones((vector[element_idx[::step],:].shape[0],1))]) - - # # self.builders[1].interpolator.set_normal_constraints(norm_pts) - # self.builders[1].data_added=True - - gy_feature = self.builders[1].build(regularisation=regularisation[1],**kwargs) + gy_feature = self.builders[1].feature + kwargs['regularisation'] = regularisation[1] + self.builders[2].build_arguments = kwargs if gy_feature is None: logger.warning( diff --git a/LoopStructural/utils/regions.py b/LoopStructural/utils/regions.py index f2a7ab229..45567e04a 100644 --- a/LoopStructural/utils/regions.py +++ b/LoopStructural/utils/regions.py @@ -2,7 +2,7 @@ class RegionEverywhere: def __call__(self,xyz): - return np.ones(xyz.shape[0],dtype='int64') + return np.ones(xyz.shape[0],dtype='bool') class RegionFunction: def __init__(self,function): diff --git a/dev/run_model.py b/dev/run_model.py index 89535a3ea..9c8e528a7 100644 --- a/dev/run_model.py +++ b/dev/run_model.py @@ -1,9 +1,27 @@ from LoopStructural.modelling.core.geological_model_graph import GeologicalModel -from LoopStructural.datasets import load_claudius +from LoopStructural.datasets import load_intrusion, load_claudius +from LoopStructural.utils import log_to_file +from LoopStructural.visualisation import LavaVuModelViewer -data, bb = load_claudius() +data, bb = load_intrusion() +log_to_file('test.log') +model = GeologicalModel(bb[0,:],bb[1,:],rescale=False) -model = GeologicalModel(bb[0,:],bb[1,:]) model.set_model_data(data) -strati = model.create_and_add_foliation('strati') -strati.evaluate_value(model.regular_grid()) \ No newline at end of file +fault = model.create_and_add_fault('fault', + 600, + interpolatortype='FDI', + solver='pyamg', + steps=2 + ) +strati = model.create_and_add_foliation('strati', + interpolatortype='FDI', + solver='pyamg') + +# strati.evaluate_value(model.regular_grid()) +print(strati.faults) +print(fault[0].faults) +view = LavaVuModelViewer(model) +view.add_isosurface(strati) +view.add_isosurface(fault) +view.interactive() \ No newline at end of file From 9c42b79d01ac81d28b9e3fcf14cd078cad8a13b0 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Thu, 28 Jan 2021 13:29:13 +1100 Subject: [PATCH 07/29] (FEATURE) changing geological model class to use new feature/builder concept Also moving fault building into separate class --- .../modelling/core/geological_model.py | 94 ++++--------------- .../modelling/fault/fault_builder.py | 42 +++++++++ dev/run_model.py | 23 +++-- 3 files changed, 72 insertions(+), 87 deletions(-) create mode 100644 LoopStructural/modelling/fault/fault_builder.py diff --git a/LoopStructural/modelling/core/geological_model.py b/LoopStructural/modelling/core/geological_model.py index d08ddc3e5..fecef7944 100644 --- a/LoopStructural/modelling/core/geological_model.py +++ b/LoopStructural/modelling/core/geological_model.py @@ -577,7 +577,9 @@ def create_and_add_foliation(self, series_surface_data, **kwargs): self._add_faults(series_builder) # build feature - series_feature = series_builder.build(**kwargs) + # series_feature = series_builder.build(**kwargs) + series_feature = series_builder.feature + series_builder.build_arguments = kwargs series_feature.type = 'series' # see if any unconformities are above this feature if so add region # self._add_unconformity_above(series_feature)self._add_feature(series_feature) @@ -613,7 +615,9 @@ def create_and_add_dtm(self, series_surface_data, **kwargs): # self._add_faults(series_builder) # build feature - series_feature = series_builder.build(**kwargs) + # series_feature = series_builder.build(**kwargs) + series_feature = series_builder.feature + series_builder.build_arguments = kwargs series_feature.type = 'dtm' # see if any unconformities are above this feature if so add region # self._add_unconformity_above(series_feature)self._add_feature(series_feature) @@ -730,7 +734,9 @@ def create_and_add_folded_foliation(self, foliation_data, fold_frame=None, # build feature kwargs['cgw'] = 0. kwargs['fold'] = fold - series_feature = series_builder.build(**kwargs) + # series_feature = series_builder.build(**kwargs) + series_feature = series_builder.feature + series_builder.build_arguments = kwargs series_feature.type = 'series' # see if any unconformities are above this feature if so add region # self._add_unconformity_above(series_feature)self._add_feature(series_feature) @@ -971,7 +977,9 @@ def create_and_add_unconformity(self, unconformity_surface_data, **kwargs): self._add_faults(unconformity_feature_builder) # build feature - uc_feature_base = unconformity_feature_builder.build(**kwargs) + # uc_feature_base = unconformity_feature_builder.build(**kwargs) + uc_feature_base = unconformity_feature_builder.feature + unconformity_feature_builder.build_arguments = kwargs uc_feature_base.type = 'unconformity_base' # uc_feature = UnconformityFeature(uc_feature_base,0) # iterate over existing features and add the unconformity as a @@ -1071,7 +1079,9 @@ def create_and_add_domain_fault(self, fault_surface_data, **kwargs): self._add_faults(domain_fault_feature_builder) # build feature - domain_fault = domain_fault_feature_builder.build(**kwargs) + # domain_fault = domain_fault_feature_builder.build(**kwargs) + domain_fault = domain_fault_feature_builder.feature + domain_fault_feature_builder.build_arguments = kwargs domain_fault.type = 'domain_fault' self._add_feature(domain_fault) self._add_domain_fault_below(domain_fault) @@ -1108,80 +1118,8 @@ def create_and_add_fault(self, fault_surface_data, displacement, renormalise=Tru # add data fault_frame_data = self.data[ self.data['feature_name'] == fault_surface_data].copy() - if 'coord' not in fault_frame_data: - fault_frame_data['coord'] = 0 - vals = fault_frame_data['val'] - if len(np.unique(vals[~np.isnan(vals)])) == 1 and renormalise: - logger.info("Setting fault ellipsoid to 1/3 of fault length") - xyz = fault_frame_data[['X', 'Y', 'Z']].to_numpy() - p1 = xyz[0, :] # fault_frame_data.loc[0 ,['X','Y']] - p2 = xyz[-1, :] # fault_frame_data.loc[-1 ,['X','Y']] - # get a vector that goes from p1-p2 and normalise - vector = p1 - p2 - length = np.linalg.norm(vector) - vector /= length - # now create the orthogonal vector - # newvector = np.zeros(3) - length /= 3 - # length/=2 - # print(fault_frame_data) - mask = ~np.isnan(fault_frame_data['gx']) - vectors = fault_frame_data[mask][['gx', 'gy', 'gz']].to_numpy() - lengths = np.linalg.norm(vectors, axis=1) - vectors /= lengths[:, None] - # added 20/08 rescale fault ellipsoid for m2l - # vectors*=length - fault_frame_data.loc[mask, ['gx', 'gy', 'gz']] = vectors - if 'strike' in fault_frame_data.columns and 'dip' in \ - fault_frame_data.columns: - fault_frame_data = fault_frame_data.drop(['dip', 'strike'], - axis=1) - # print(fault_frame_data) - # if there is no slip direction data assume vertical - if fault_frame_data[fault_frame_data['coord'] == 1].shape[0] == 0: - logger.info("Adding fault frame slip") - loc = np.mean(fault_frame_data[['X', 'Y', 'Z']], axis=0) - coord1 = pd.DataFrame([[loc[0], loc[1], loc[2], 0, 0, -1]], - columns=normal_vector_headers()) - coord1['coord'] = 1 - fault_frame_data = pd.concat([fault_frame_data, coord1], - sort=False) - - if fault_frame_data[fault_frame_data['coord'] == 2].shape[0] == 0: - logger.info("Adding fault extent data as first and last point") - ## first and last point of the line - value_data = fault_frame_data[fault_frame_data['val'] == 0] - if not value_data.empty: - coord2 = value_data.iloc[[0, len(value_data) - 1]] - coord2 = coord2.reset_index(drop=True) - c2_scale = kwargs.get('length_scale',1.) - coord2.loc[0, 'val'] = -1/c2_scale - coord2.loc[1, 'val'] = 1/c2_scale - coord2['coord'] = 2 - fault_frame_data = pd.concat([fault_frame_data, coord2], - sort=False) + fault_frame_builder.add_data_from_data_frame(fault_frame_data) - # if there is no fault slip data then we could find the strike of - # the fault and build - # the second coordinate - # if we add a region to the fault then the fault operator doesn't - # work but for visualisation - # we want to add a region! - - if 'splayregion' in kwargs and 'splay' in kwargs: - # result['splayregionfeature'] = RegionFeature(kwargs['splayregion']) - # apply splay to all parts of fault frame - for i in range(3): - # work out the values of the nodes where we want hard - # constraints - idc = np.arange(0, interpolator.support.n_nodes)[ - kwargs['splayregion'](interpolator.support.nodes)] - val = kwargs['splay'][i].evaluate_value( - interpolator.support.nodes[ - kwargs['splayregion'](interpolator.support.nodes), :]) - mask = ~np.isnan(val) - fault_frame_builder[i].interpolator.add_equality_constraints( - idc[mask], val[mask]) # check if this fault overprint any existing faults exist in the stack overprinted = kwargs.get('overprinted', []) overprinted_faults = [] diff --git a/LoopStructural/modelling/fault/fault_builder.py b/LoopStructural/modelling/fault/fault_builder.py new file mode 100644 index 000000000..0966cb9bc --- /dev/null +++ b/LoopStructural/modelling/fault/fault_builder.py @@ -0,0 +1,42 @@ +from ..features.structural_frame_builder import StructuralFrameBuilder +class FaultBuilder(StructuralFrameBuilder): + def __init__(self,interpolator=None,interpolators=None,**kwargs): + StructuralFrameBuilder.__init__(self,interpolator,interpolators,kwargs) + + def create_data_from_geometry(self, + fault_center, + fault_dip_direction, + influence_distance, + horizontal_radius, + vertical_radius): + + normal_vector[0] = np.sin(np.deg2rad(fault_dip_direction)) + normal_vector[1] = np.cos(np.deg2rad(fault_dip_direction)) + strike_vector[0] = normal_vector[1] + strike_vector[1] = -normal_vector[0] + slip_vector[2]=1 + fault_edges[0,:] = fault_center[:3]+normal_vector*influence_distance + fault_edges[1,:] = fault_center[:3]-normal_vector*influence_distance + fault_tips[0,:] = fault_center[:3]+strike_vector*horizontal_radius + fault_tips[1,:] = fault_center[:3]-strike_vector*horizontal_radius + fault_depth[0,:] = fault_center[:3]+slip_vector*vertical_radius + fault_depth[1,:] = fault_center[:3]-slip_vector*vertical_radius + fault_locations.loc[len(fault_locations),['X','Y','Z','feature_name','val','coord']] = [fault_edges[0,0],fault_edges[0,1],fault_edges[0,2],f,1,0] + fault_locations.loc[len(fault_locations),['X','Y','Z','feature_name','val','coord']] = [fault_edges[1,0],fault_edges[1,1],fault_edges[1,2],f,-1,0] + fault_locations.loc[len(fault_locations),['X','Y','Z','feature_name','val','coord']] = [fault_tips[0,0],fault_tips[0,1],fault_tips[0,2],f,1,2] + fault_locations.loc[len(fault_locations),['X','Y','Z','feature_name','val','coord']] = [fault_tips[1,0],fault_tips[1,1],fault_tips[1,2],f,-1,2] + # add strike vector to constraint fault extent + fault_orientations.loc[len(fault_orientations),['X','Y','Z','feature_name','nx','ny','nz','coord']] = [fault_center[0],fault_center[1],fault_center[2],f, fault_centers[3]-90,2] + + def add_splay(self,splayregion,splay): + for i in range(3): + # work out the values of the nodes where we want hard + # constraints + idc = np.arange(0, interpolator.support.n_nodes)[ + kwargs['splayregion'](interpolator.support.nodes)] + val = kwargs['splay'][i].evaluate_value( + interpolator.support.nodes[ + kwargs['splayregion'](interpolator.support.nodes), :]) + mask = ~np.isnan(val) + fault_frame_builder[i].interpolator.add_equality_constraints( + idc[mask], val[mask]) \ No newline at end of file diff --git a/dev/run_model.py b/dev/run_model.py index 9c8e528a7..eded4b14a 100644 --- a/dev/run_model.py +++ b/dev/run_model.py @@ -1,4 +1,6 @@ -from LoopStructural.modelling.core.geological_model_graph import GeologicalModel +# from LoopStructural.modelling.core.geological_model_graph import GeologicalModel +from LoopStructural import GeologicalModel +import numpy as np from LoopStructural.datasets import load_intrusion, load_claudius from LoopStructural.utils import log_to_file from LoopStructural.visualisation import LavaVuModelViewer @@ -11,17 +13,20 @@ fault = model.create_and_add_fault('fault', 600, interpolatortype='FDI', + nelements=1e3, solver='pyamg', steps=2 ) strati = model.create_and_add_foliation('strati', interpolatortype='FDI', solver='pyamg') - -# strati.evaluate_value(model.regular_grid()) -print(strati.faults) -print(fault[0].faults) -view = LavaVuModelViewer(model) -view.add_isosurface(strati) -view.add_isosurface(fault) -view.interactive() \ No newline at end of file +print(model ) +strati.evaluate_value(model.regular_grid()) +# # print(strati.faults) +# print(fault[0].faults) +# view = LavaVuModelViewer(model,background='white') +# view.add_isosurface(strati,slices=np.unique(data.loc[~np.isnan(data['val']),'val'])) +# view.add_isosurface(fault,value=0) +# view.add_data(strati) +# # view.add_vector_field(fault,locations=model.regular_grid()[::10,:]) +# view.interactive() \ No newline at end of file From 3467d4561eec0ee086f17e4871519b6c15945c5e Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Thu, 28 Jan 2021 13:33:06 +1100 Subject: [PATCH 08/29] (FEATURE) creating stratigraphic column class --- LoopStructural/modelling/core/stratigraphic_column.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 LoopStructural/modelling/core/stratigraphic_column.py diff --git a/LoopStructural/modelling/core/stratigraphic_column.py b/LoopStructural/modelling/core/stratigraphic_column.py new file mode 100644 index 000000000..e8b3584cc --- /dev/null +++ b/LoopStructural/modelling/core/stratigraphic_column.py @@ -0,0 +1,5 @@ +class StratigraphicColumn: + def __init__(self): + pass + def add_series(self,feature,name,maximum,minimum,colour): + pass \ No newline at end of file From 0bc8201cbd6f998a22f974b8fef88d15aeda2a69 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Thu, 28 Jan 2021 14:17:00 +1100 Subject: [PATCH 09/29] (FEATURE) working on fault geometry params --- .../modelling/fault/fault_builder.py | 54 +++++++++++++++---- .../features/geological_feature_builder.py | 2 +- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/LoopStructural/modelling/fault/fault_builder.py b/LoopStructural/modelling/fault/fault_builder.py index 0966cb9bc..0398ba1a9 100644 --- a/LoopStructural/modelling/fault/fault_builder.py +++ b/LoopStructural/modelling/fault/fault_builder.py @@ -1,33 +1,67 @@ from ..features.structural_frame_builder import StructuralFrameBuilder class FaultBuilder(StructuralFrameBuilder): def __init__(self,interpolator=None,interpolators=None,**kwargs): + """A specialised structural frame builder for building a fault + + Parameters + ---------- + interpolator : GeologicalInterpolator, optional + the interpolator to use for building the fault frame, by default None + interpolators : [GeologicalInterpolator, GeologicalInterpolator, GeologicalInterpolator], optional + a list of interpolators to use for building the fault frame, by default None + """ StructuralFrameBuilder.__init__(self,interpolator,interpolators,kwargs) def create_data_from_geometry(self, + data, fault_center, - fault_dip_direction, + normal_vector, + slip_vector, influence_distance, horizontal_radius, vertical_radius): + """Generate the required data for building a fault frame for a fault with the + specified parameters + + Parameters + ---------- + data : DataFrame, + model data + fault_center : np.array(3) + x,y,z coordinates of the fault center + normal_vector : np.array(3) + x,y,z components of normal vector to fault, single observation usually + average direction + slip_vector : np.array(3) + x,y,z components of slip vector for the fault, single observation usually + average direction + influence_distance : double + distance away from fault for the fault volume + horizontal_radius : double + fault extent + vertical_radius : double + fault volume radius in the slip direction + """ normal_vector[0] = np.sin(np.deg2rad(fault_dip_direction)) normal_vector[1] = np.cos(np.deg2rad(fault_dip_direction)) - strike_vector[0] = normal_vector[1] - strike_vector[1] = -normal_vector[0] - slip_vector[2]=1 + strike_vector = np.cross(normal_vector,slip_vector) fault_edges[0,:] = fault_center[:3]+normal_vector*influence_distance fault_edges[1,:] = fault_center[:3]-normal_vector*influence_distance fault_tips[0,:] = fault_center[:3]+strike_vector*horizontal_radius fault_tips[1,:] = fault_center[:3]-strike_vector*horizontal_radius fault_depth[0,:] = fault_center[:3]+slip_vector*vertical_radius fault_depth[1,:] = fault_center[:3]-slip_vector*vertical_radius - fault_locations.loc[len(fault_locations),['X','Y','Z','feature_name','val','coord']] = [fault_edges[0,0],fault_edges[0,1],fault_edges[0,2],f,1,0] - fault_locations.loc[len(fault_locations),['X','Y','Z','feature_name','val','coord']] = [fault_edges[1,0],fault_edges[1,1],fault_edges[1,2],f,-1,0] - fault_locations.loc[len(fault_locations),['X','Y','Z','feature_name','val','coord']] = [fault_tips[0,0],fault_tips[0,1],fault_tips[0,2],f,1,2] - fault_locations.loc[len(fault_locations),['X','Y','Z','feature_name','val','coord']] = [fault_tips[1,0],fault_tips[1,1],fault_tips[1,2],f,-1,2] + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_edges[0,0],fault_edges[0,1],fault_edges[0,2],f,1,0] + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_edges[1,0],fault_edges[1,1],fault_edges[1,2],f,-1,0] + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_tips[0,0],fault_tips[0,1],fault_tips[0,2],f,1,2] + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_tips[1,0],fault_tips[1,1],fault_tips[1,2],f,-1,2] # add strike vector to constraint fault extent - fault_orientations.loc[len(fault_orientations),['X','Y','Z','feature_name','nx','ny','nz','coord']] = [fault_center[0],fault_center[1],fault_center[2],f, fault_centers[3]-90,2] - + + data.loc[len(data),['X','Y','Z','feature_name','nx','ny','nz','coord']] = [fault_center[0],fault_center[1],fault_center[2],\ + f, fault_extent_vector[0], fault_extent_vector[1], fault_extent_vector[2], 2] + self.add_data_from_data_frame(data) + def add_splay(self,splayregion,splay): for i in range(3): # work out the values of the nodes where we want hard diff --git a/LoopStructural/modelling/features/geological_feature_builder.py b/LoopStructural/modelling/features/geological_feature_builder.py index 2231ea6e8..66d10a083 100644 --- a/LoopStructural/modelling/features/geological_feature_builder.py +++ b/LoopStructural/modelling/features/geological_feature_builder.py @@ -108,7 +108,7 @@ def add_fault(self, fault): self._up_to_date = False self.faults.append(fault) - def add_data_from_data_frame(self, data_frame): + def add_data_from_data_frame(self, data_frame, overwrite = False): """ Extract data from a pandas dataframe with columns for From afe3093d07feb341124e39cb7d067d2a2d3546e7 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Thu, 28 Jan 2021 16:13:35 +1100 Subject: [PATCH 10/29] (FEATURE) adding fault builder to geomodel --- .../modelling/core/geological_model.py | 12 +++++-- LoopStructural/modelling/fault/__init__.py | 1 + .../modelling/fault/fault_builder.py | 31 +++++++++++-------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/LoopStructural/modelling/core/geological_model.py b/LoopStructural/modelling/core/geological_model.py index fecef7944..47006e673 100644 --- a/LoopStructural/modelling/core/geological_model.py +++ b/LoopStructural/modelling/core/geological_model.py @@ -25,6 +25,7 @@ from LoopStructural.interpolators.structured_grid import StructuredGrid from LoopStructural.interpolators.structured_tetra import TetMesh from LoopStructural.modelling.fault.fault_segment import FaultSegment +from LoopStructural.modelling.fault import FaultBuilder from LoopStructural.modelling.features import (GeologicalFeatureInterpolator, RegionFeature, StructuralFrameBuilder, @@ -1092,13 +1093,19 @@ def create_and_add_domain_fault(self, fault_surface_data, **kwargs): # evaluated where the unconformity is positive return domain_fault_uc - def create_and_add_fault(self, fault_surface_data, displacement, renormalise=True, **kwargs): + def create_and_add_fault(self, fault_surface_data, displacement, fault_extent = None, fault_influence = None, fault_vectical_radius = None, **kwargs): """ Parameters ---------- fault_surface_data : string name of the fault surface data in the dataframe displacement : displacement magnitude + fault_extent : [type], optional + [description], by default None + fault_influence : [type], optional + [description], by default None + fault_vectical_radius : [type], optional + [description], by default None kwargs : additional kwargs for Fault and interpolators Returns @@ -1112,10 +1119,11 @@ def create_and_add_fault(self, fault_surface_data, displacement, renormalise=Tru displacement_scaled = displacement / self.scale_factor # create fault frame interpolator = self.get_interpolator(**kwargs) - fault_frame_builder = StructuralFrameBuilder(interpolator, + fault_frame_builder = FaultBuilder(interpolator, name=fault_surface_data, **kwargs) # add data + fault_vector fault_frame_data = self.data[ self.data['feature_name'] == fault_surface_data].copy() diff --git a/LoopStructural/modelling/fault/__init__.py b/LoopStructural/modelling/fault/__init__.py index 233ab7709..e57e097e5 100644 --- a/LoopStructural/modelling/fault/__init__.py +++ b/LoopStructural/modelling/fault/__init__.py @@ -1,3 +1,4 @@ from .fault_function import Composite, CubicFunction, Ones, Zeros from .fault_function_feature import FaultDisplacementFeature from .fault_segment import FaultSegment +from .fault_builder import FaultBuilder \ No newline at end of file diff --git a/LoopStructural/modelling/fault/fault_builder.py b/LoopStructural/modelling/fault/fault_builder.py index 0398ba1a9..fdb562892 100644 --- a/LoopStructural/modelling/fault/fault_builder.py +++ b/LoopStructural/modelling/fault/fault_builder.py @@ -17,9 +17,9 @@ def create_data_from_geometry(self, fault_center, normal_vector, slip_vector, - influence_distance, - horizontal_radius, - vertical_radius): + influence_distance = None, + horizontal_radius = None, + vertical_radius = None): """Generate the required data for building a fault frame for a fault with the specified parameters @@ -46,16 +46,21 @@ def create_data_from_geometry(self, normal_vector[0] = np.sin(np.deg2rad(fault_dip_direction)) normal_vector[1] = np.cos(np.deg2rad(fault_dip_direction)) strike_vector = np.cross(normal_vector,slip_vector) - fault_edges[0,:] = fault_center[:3]+normal_vector*influence_distance - fault_edges[1,:] = fault_center[:3]-normal_vector*influence_distance - fault_tips[0,:] = fault_center[:3]+strike_vector*horizontal_radius - fault_tips[1,:] = fault_center[:3]-strike_vector*horizontal_radius - fault_depth[0,:] = fault_center[:3]+slip_vector*vertical_radius - fault_depth[1,:] = fault_center[:3]-slip_vector*vertical_radius - data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_edges[0,0],fault_edges[0,1],fault_edges[0,2],f,1,0] - data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_edges[1,0],fault_edges[1,1],fault_edges[1,2],f,-1,0] - data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_tips[0,0],fault_tips[0,1],fault_tips[0,2],f,1,2] - data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_tips[1,0],fault_tips[1,1],fault_tips[1,2],f,-1,2] + if influence_distance is not None: + fault_edges[0,:] = fault_center[:3]+normal_vector*influence_distance + fault_edges[1,:] = fault_center[:3]-normal_vector*influence_distance + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_edges[0,0],fault_edges[0,1],fault_edges[0,2],f,1,0] + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_edges[1,0],fault_edges[1,1],fault_edges[1,2],f,-1,0] + if horizontal_radius is not None: + fault_tips[0,:] = fault_center[:3]+strike_vector*horizontal_radius + fault_tips[1,:] = fault_center[:3]-strike_vector*horizontal_radius + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_tips[0,0],fault_tips[0,1],fault_tips[0,2],f,1,2] + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_tips[1,0],fault_tips[1,1],fault_tips[1,2],f,-1,2] + if vertical_radius is not None: + fault_depth[0,:] = fault_center[:3]+slip_vector*vertical_radius + fault_depth[1,:] = fault_center[:3]-slip_vector*vertical_radius + #TODO need to add data here + # add strike vector to constraint fault extent data.loc[len(data),['X','Y','Z','feature_name','nx','ny','nz','coord']] = [fault_center[0],fault_center[1],fault_center[2],\ From 14379d631a8cfd15c1b93d4a1c5bb09a767734b9 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Mon, 1 Feb 2021 15:06:47 +1100 Subject: [PATCH 11/29] (DEV) m2l test case --- dev/run_m2l_model.py | 55 ++++++++++++++++++++++++++++++++++++++++++++ dev/run_model.py | 13 +++++------ 2 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 dev/run_m2l_model.py diff --git a/dev/run_m2l_model.py b/dev/run_m2l_model.py new file mode 100644 index 000000000..8df80abfd --- /dev/null +++ b/dev/run_m2l_model.py @@ -0,0 +1,55 @@ +from LoopStructural import GeologicalModel +from LoopStructural.visualisation import LavaVuModelViewer +from LoopStructural import GeologicalModel +from LoopStructural.utils import log_to_file +import numpy as np +# log_to_file('dev/ls.log') +fault_params = {'interpolatortype':'FDI', + 'nelements':1e4, + # 'data_region':0, + 'solver':'pyamg', + 'step':10, + 'cpw':10, + 'npw':10, + 'tol':1e-8 + } +foliation_params = {'interpolatortype':'FDI' , # 'interpolatortype':'PLI', + 'nelements':1e4, # how many tetras/voxels + 'data_region':.3, # how much to extend nterpolation around box + 'solver':'pyamg', + 'damp':True} + +fault_params = {'interpolatortype':'FDI', + 'nelements':1e4, + # 'data_region':.2, + 'solver':'lu', +# overprints:overprints, + 'cpw':10, + 'npw':10} +foliation_params = {'nelements':1e5, # how many tetras/voxels + 'buffer':2.5, # how much to extend nterpolation around box + 'solver':'pyamg', + 'npw':10, + 'cpw':10, + 'interpolatortype':'FDI', + 'damp':True} + +model, m2l_data = GeologicalModel.from_map2loop_directory('./dev/unconf', + skip_faults=False, + # rescale=False, + fault_params=fault_params, + foliation_params=foliation_params) +# print(model.data[model.data['coord']==1]) +# # print(model.features[1][0].builder.data) +# for f in features: +# f.builder.update() +# model.features[1][0].builder.update()#evaluate_value(np.array([[0,0,0]])) +# print(model.features[1][0].interpolator.support) +# print(model.support) +view = LavaVuModelViewer(model,vertical_exaggeration=1) +view.add_isosurface(model.features[1][0]) +# # view.interactive() +view.add_model_surfaces(faults=True)#filename=filename) +# # # view.add_data(model['supergroup_0']) +# view.add_fault_displacements() +view.interactive() \ No newline at end of file diff --git a/dev/run_model.py b/dev/run_model.py index eded4b14a..90d370b8f 100644 --- a/dev/run_model.py +++ b/dev/run_model.py @@ -20,13 +20,12 @@ strati = model.create_and_add_foliation('strati', interpolatortype='FDI', solver='pyamg') -print(model ) strati.evaluate_value(model.regular_grid()) # # print(strati.faults) # print(fault[0].faults) -# view = LavaVuModelViewer(model,background='white') -# view.add_isosurface(strati,slices=np.unique(data.loc[~np.isnan(data['val']),'val'])) -# view.add_isosurface(fault,value=0) -# view.add_data(strati) -# # view.add_vector_field(fault,locations=model.regular_grid()[::10,:]) -# view.interactive() \ No newline at end of file +view = LavaVuModelViewer(model,background='white') +view.add_isosurface(strati,slices=np.unique(data.loc[~np.isnan(data['val']),'val'])) +view.add_isosurface(fault,value=0) +view.add_data(strati) +# view.add_vector_field(fault,locations=model.regular_grid()[::10,:]) +view.interactive() \ No newline at end of file From 5f14488fff0fac1a1bfd8ed4bcbc2b54eb9d1e87 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Mon, 1 Feb 2021 15:07:48 +1100 Subject: [PATCH 12/29] (DEV) adding fault geometry arguments --- .gitignore | 3 +- .../interpolators/discrete_interpolator.py | 1 - .../modelling/core/geological_model.py | 43 +++++++++-- .../modelling/fault/fault_builder.py | 76 +++++++++++++------ .../features/geological_feature_builder.py | 17 ++++- LoopStructural/utils/map2loop.py | 29 ++++--- 6 files changed, 123 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index c132eadeb..4495acc14 100644 --- a/.gitignore +++ b/.gitignore @@ -127,4 +127,5 @@ docs/source/_autosummary/* docs/source/auto_examples/* examples/*/*.png docs/source/test/* -examples/*.png \ No newline at end of file +examples/*.png +dev/unconf/* \ No newline at end of file diff --git a/LoopStructural/interpolators/discrete_interpolator.py b/LoopStructural/interpolators/discrete_interpolator.py index 55a8ae366..5d84ef21c 100644 --- a/LoopStructural/interpolators/discrete_interpolator.py +++ b/LoopStructural/interpolators/discrete_interpolator.py @@ -156,7 +156,6 @@ def add_constraints_to_least_squares(self, A, B, idc, name='undefined'): A = np.array(A) B = np.array(B) idc = np.array(idc) - nr = A.shape[0] if A.shape != idc.shape: return diff --git a/LoopStructural/modelling/core/geological_model.py b/LoopStructural/modelling/core/geological_model.py index 47006e673..a44691663 100644 --- a/LoopStructural/modelling/core/geological_model.py +++ b/LoopStructural/modelling/core/geological_model.py @@ -1093,7 +1093,15 @@ def create_and_add_domain_fault(self, fault_surface_data, **kwargs): # evaluated where the unconformity is positive return domain_fault_uc - def create_and_add_fault(self, fault_surface_data, displacement, fault_extent = None, fault_influence = None, fault_vectical_radius = None, **kwargs): + def create_and_add_fault(self, + fault_surface_data, + displacement, + fault_slip_vector=None, + fault_center = None, + fault_extent = None, + fault_influence = None, + fault_vectical_radius = None, + **kwargs): """ Parameters ---------- @@ -1123,11 +1131,27 @@ def create_and_add_fault(self, fault_surface_data, displacement, fault_extent = name=fault_surface_data, **kwargs) # add data - fault_vector - fault_frame_data = self.data[ - self.data['feature_name'] == fault_surface_data].copy() - - fault_frame_builder.add_data_from_data_frame(fault_frame_data) + fault_frame_data = self.data[ self.data['feature_name'] == fault_surface_data].copy() + mask = np.logical_and(fault_frame_data['coord']==0,~np.isnan(fault_frame_data['gz'])) + fault_normal_vector = fault_frame_data.loc[mask,['gx','gy','gz']].mean(axis=0).to_numpy() + mask = np.logical_and(fault_frame_data['coord']==1,~np.isnan(fault_frame_data['gz'])) + if fault_slip_vector is None: + fault_slip_vector = fault_frame_data.loc[mask,['gx','gy','gz']].mean(axis=0).to_numpy() + if fault_center is None: + # if we haven't defined a fault centre take the center of mass for lines assocaited with + # the fault trace + mask = np.logical_and(fault_frame_data['coord']==0,fault_frame_data['val']==0) + fault_center = fault_frame_data.loc[mask,['X','Y','Z']].mean(axis=0).to_numpy() + fault_frame_builder.create_data_from_geometry(fault_frame_data, + self.scale(fault_center), + fault_normal_vector, + fault_slip_vector, + influence_distance=fault_influence/self.scale_factor, + horizontal_radius=fault_extent/self.scale_factor, + vertical_radius=fault_vectical_radius/self.scale_factor + ) + fault_frame_builder.set_mesh_geometry(0.1) + # fault_frame_builder.add_data_from_data_frame(fault_frame_data) # check if this fault overprint any existing faults exist in the stack overprinted = kwargs.get('overprinted', []) overprinted_faults = [] @@ -1193,8 +1217,11 @@ def scale(self, points, inplace=True): """ if inplace==False: points = points.copy() - - points[:, :] -= self.origin + # if len(points.shape) == 1: + # points = points[None,:] + # if len(points.shape) != 2: + # logger.error("cannot scale array of dimensions".format(len(points.shape))) + points -= self.origin points /= self.scale_factor return points diff --git a/LoopStructural/modelling/fault/fault_builder.py b/LoopStructural/modelling/fault/fault_builder.py index fdb562892..5e51bfb46 100644 --- a/LoopStructural/modelling/fault/fault_builder.py +++ b/LoopStructural/modelling/fault/fault_builder.py @@ -1,4 +1,6 @@ from ..features.structural_frame_builder import StructuralFrameBuilder + +import numpy as np class FaultBuilder(StructuralFrameBuilder): def __init__(self,interpolator=None,interpolators=None,**kwargs): """A specialised structural frame builder for building a fault @@ -10,8 +12,15 @@ def __init__(self,interpolator=None,interpolators=None,**kwargs): interpolators : [GeologicalInterpolator, GeologicalInterpolator, GeologicalInterpolator], optional a list of interpolators to use for building the fault frame, by default None """ - StructuralFrameBuilder.__init__(self,interpolator,interpolators,kwargs) - + + StructuralFrameBuilder.__init__(self,interpolator,interpolators,**kwargs) + self.origin = np.array([np.nan,np.nan,np.nan]) + self.maximum = np.array([np.nan,np.nan,np.nan]) + + def update_geometry(self,points): + self.origin = np.nanmin(np.array([np.min(points,axis=0),self.origin]),axis=0) + self.maximum = np.nanmax(np.array([np.max(points,axis=0),self.maximum]),axis=0) + def create_data_from_geometry(self, data, fault_center, @@ -42,31 +51,52 @@ def create_data_from_geometry(self, vertical_radius : double fault volume radius in the slip direction """ - - normal_vector[0] = np.sin(np.deg2rad(fault_dip_direction)) - normal_vector[1] = np.cos(np.deg2rad(fault_dip_direction)) strike_vector = np.cross(normal_vector,slip_vector) - if influence_distance is not None: - fault_edges[0,:] = fault_center[:3]+normal_vector*influence_distance - fault_edges[1,:] = fault_center[:3]-normal_vector*influence_distance - data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_edges[0,0],fault_edges[0,1],fault_edges[0,2],f,1,0] - data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_edges[1,0],fault_edges[1,1],fault_edges[1,2],f,-1,0] - if horizontal_radius is not None: - fault_tips[0,:] = fault_center[:3]+strike_vector*horizontal_radius - fault_tips[1,:] = fault_center[:3]-strike_vector*horizontal_radius - data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_tips[0,0],fault_tips[0,1],fault_tips[0,2],f,1,2] - data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = [fault_tips[1,0],fault_tips[1,1],fault_tips[1,2],f,-1,2] - if vertical_radius is not None: - fault_depth[0,:] = fault_center[:3]+slip_vector*vertical_radius - fault_depth[1,:] = fault_center[:3]-slip_vector*vertical_radius - #TODO need to add data here - + fault_edges = np.zeros((2,3)) + fault_tips = np.zeros((2,3)) + fault_depth = np.zeros((2,3)) + if fault_center is not None: + if influence_distance is not None: + fault_edges[0,:] = fault_center[:3]+normal_vector*influence_distance + fault_edges[1,:] = fault_center[:3]-normal_vector*influence_distance + self.update_geometry(fault_edges) + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = \ + [fault_edges[0,0],fault_edges[0,1],fault_edges[0,2],self.name,1,0] + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = \ + [fault_edges[1,0],fault_edges[1,1],fault_edges[1,2],self.name,-1,0] + if horizontal_radius is not None: + fault_tips[0,:] = fault_center[:3]+strike_vector*horizontal_radius + fault_tips[1,:] = fault_center[:3]-strike_vector*horizontal_radius + self.update_geometry(fault_tips) + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = \ + [fault_tips[0,0],fault_tips[0,1],fault_tips[0,2],self.name,1,2] + data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = \ + [fault_tips[1,0],fault_tips[1,1],fault_tips[1,2],self.name,-1,2] + if vertical_radius is not None: + fault_depth[0,:] = fault_center[:3]+slip_vector*vertical_radius + fault_depth[1,:] = fault_center[:3]-slip_vector*vertical_radius + self.update_geometry(fault_depth) + #TODO need to add data here + data.loc[len(data),['X','Y','Z','feature_name','nx','ny','nz','coord']] =\ + [fault_center[0],fault_center[1],fault_center[2],self.name,slip_vector[0],slip_vector[1],slip_vector[2],1] # add strike vector to constraint fault extent - - data.loc[len(data),['X','Y','Z','feature_name','nx','ny','nz','coord']] = [fault_center[0],fault_center[1],fault_center[2],\ - f, fault_extent_vector[0], fault_extent_vector[1], fault_extent_vector[2], 2] + data.loc[len(data),['X','Y','Z','feature_name','nx','ny','nz','coord']] = [fault_center[0],fault_center[1],fault_center[2],\ + self.name, strike_vector[0], strike_vector[1], strike_vector[2], 2] self.add_data_from_data_frame(data) + def set_mesh_geometry(self,buffer): + """set the mesh geometry + + Parameters + ---------- + buffer : double + percentage of length to add to edges + """ + length = self.maximum-self.origin + # for builder in self.builders: + # all three coordinates share the same support + self.builders[0].set_interpolation_geometry(self.origin-length*buffer,self.maximum-length*buffer) + def add_splay(self,splayregion,splay): for i in range(3): # work out the values of the nodes where we want hard diff --git a/LoopStructural/modelling/features/geological_feature_builder.py b/LoopStructural/modelling/features/geological_feature_builder.py index 66d10a083..658fa825b 100644 --- a/LoopStructural/modelling/features/geological_feature_builder.py +++ b/LoopStructural/modelling/features/geological_feature_builder.py @@ -208,7 +208,6 @@ def add_data_to_interpolator(self, constrained=False, force_constrained=False, * logger.error("Not enough constraints for scalar field add more") # self.interpolator.reset() mask = ~np.isnan(data.loc[:,val_name()].to_numpy()) - # add value constraints if mask.shape[0]>0: value_data = data.loc[mask[:,0],xyz_names()+val_name()+weight_name()].to_numpy() @@ -340,6 +339,21 @@ def get_data_locations(self): """ return self.data.loc[:, xyz_names()].to_numpy() + def set_interpolation_geometry(self,origin,maximum): + """Update the interpolation support geometry to new bounding box + + Parameters + ---------- + origin : np.array(3) + origin vector + maximum : np.array(3) + maximum vector + """ + logger.info("Setting mesh origin: {} {} {} ".format(origin[0],origin[1],origin[2])) + logger.info("Setting mesh maximum: {} {} {}".format(maximum[0],maximum[1],maximum[2])) + self.interpolator.support.origin = origin + self.interpolator.support.maximum = maximum + self._up_to_date = False def build(self, fold=None, fold_weights={}, data_region=None, **kwargs): """ @@ -391,7 +405,6 @@ def build(self, fold=None, fold_weights={}, data_region=None, **kwargs): if 'cgw' not in kwargs: # try adding very small cg kwargs['cgw'] = 0.0 - self.interpolator.setup_interpolator(**kwargs) self.interpolator.solve_system(**kwargs) self._up_to_date = True diff --git a/LoopStructural/utils/map2loop.py b/LoopStructural/utils/map2loop.py index f44ad0fa6..26c8700e8 100644 --- a/LoopStructural/utils/map2loop.py +++ b/LoopStructural/utils/map2loop.py @@ -224,19 +224,18 @@ def process_map2loop(m2l_directory, flags={}): fault_tips[1,:] = fault_centers[:3]-strike_vector*fault_centers[5] # fault_depth[0,:] = fault_centers[:3]+slip_vector*fault_centers[5] # fault_depth[1,:] = fault_centers[:3]-slip_vector*fault_centers[5] - fault_locations.loc[len(fault_locations),['X','Y','Z','formation','val','coord']] = [fault_edges[0,0],fault_edges[0,1],fault_edges[0,2],f,1,0] - fault_locations.loc[len(fault_locations),['X','Y','Z','formation','val','coord']] = [fault_edges[1,0],fault_edges[1,1],fault_edges[1,2],f,-1,0] - fault_locations.loc[len(fault_locations),['X','Y','Z','formation','val','coord']] = [fault_tips[0,0],fault_tips[0,1],fault_tips[0,2],f,1,2] - fault_locations.loc[len(fault_locations),['X','Y','Z','formation','val','coord']] = [fault_tips[1,0],fault_tips[1,1],fault_tips[1,2],f,-1,2] - # add strike vector to constraint fault extent - fault_orientations.loc[len(fault_orientations),['X','Y','Z','formation','DipDirection','coord']] = [fault_centers[0],fault_centers[1],fault_centers[2],f, fault_centers[3]-90,2] - fault_orientations.loc[len(fault_orientations),['X','Y','Z','formation','dip','coord']] = [fault_centers[0],fault_centers[1],fault_centers[2],f, 0,2] + # fault_locations.loc[len(fault_locations),['X','Y','Z','formation','val','coord']] = [fault_edges[0,0],fault_edges[0,1],fault_edges[0,2],f,1,0] + # fault_locations.loc[len(fault_locations),['X','Y','Z','formation','val','coord']] = [fault_edges[1,0],fault_edges[1,1],fault_edges[1,2],f,-1,0] + # fault_locations.loc[len(fault_locations),['X','Y','Z','formation','val','coord']] = [fault_tips[0,0],fault_tips[0,1],fault_tips[0,2],f,1,2] + # fault_locations.loc[len(fault_locations),['X','Y','Z','formation','val','coord']] = [fault_tips[1,0],fault_tips[1,1],fault_tips[1,2],f,-1,2] + # # add strike vector to constraint fault extent + # fault_orientations.loc[len(fault_orientations),['X','Y','Z','formation','DipDirection','coord']] = [fault_centers[0],fault_centers[1],fault_centers[2],f, fault_centers[3]-90,2] + # fault_orientations.loc[len(fault_orientations),['X','Y','Z','formation','dip','coord']] = [fault_centers[0],fault_centers[1],fault_centers[2],f, 0,2] # print('downthro',displacements_numpy[index, 1]) fault_orientations['strike'] = fault_orientations['DipDirection'] - 90 fault_orientations[['gx', 'gy', 'gz']] = strike_dip_vector(fault_orientations['strike'], fault_orientations['dip']) - for g in groups['group'].unique(): groups.loc[groups['group']==g,'group'] = supergroups[g] # fault_orientations['strike'] = fault_orientations['DipDirection'] - 90 @@ -248,10 +247,8 @@ def process_map2loop(m2l_directory, flags={}): fault_orientations['feature_name'] = fault_orientations['formation'] fault_locations['feature_name'] = fault_locations['formation'] - - data = pd.concat([tangents, contact_orientations, contacts, fault_orientations, fault_locations]) - data.reset_index() + data.reset_index(inplace=True) return {'data': data, 'groups': groups, @@ -312,9 +309,19 @@ def build_model(m2l_data, skip_faults = False, unconformities=False, fault_param except: logger.info('No entry for %s in fault_fault_relations' % f) # continue + + fault_center = m2l_data['stratigraphic_column']['faults'][f]['FaultCenter'] + fault_influence = m2l_data['stratigraphic_column']['faults'][f]['InfluenceDistance'] + fault_extent = m2l_data['stratigraphic_column']['faults'][f]['HorizontalRadius'] + fault_vertical_radius = m2l_data['stratigraphic_column']['faults'][f]['VerticalRadius'] faults.append(model.create_and_add_fault(f, -m2l_data['max_displacement'][f], faultfunction='BaseFault', + fault_slip_vector=np.array([0,0,1]), + fault_center=fault_center, + fault_extent=fault_extent, + fault_influence=fault_influence, + fault_vectical_radius=fault_vertical_radius, overprints=overprints, **fault_params, ) From 953dfd99838c5ab6a0179b7042a36453e84bc1e1 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Mon, 1 Feb 2021 16:04:51 +1100 Subject: [PATCH 13/29] (DEV) push for testing --- LoopStructural/modelling/fault/fault_builder.py | 2 +- .../modelling/features/geological_feature.py | 1 + dev/run_m2l_model.py | 12 ++++++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/LoopStructural/modelling/fault/fault_builder.py b/LoopStructural/modelling/fault/fault_builder.py index 5e51bfb46..e9fa47ae3 100644 --- a/LoopStructural/modelling/fault/fault_builder.py +++ b/LoopStructural/modelling/fault/fault_builder.py @@ -95,7 +95,7 @@ def set_mesh_geometry(self,buffer): # for builder in self.builders: # all three coordinates share the same support - self.builders[0].set_interpolation_geometry(self.origin-length*buffer,self.maximum-length*buffer) + # self.builders[0].set_interpolation_geometry(self.origin-length*buffer,self.maximum-length*buffer) def add_splay(self,splayregion,splay): for i in range(3): diff --git a/LoopStructural/modelling/features/geological_feature.py b/LoopStructural/modelling/features/geological_feature.py index 160cc2545..ee89b522d 100644 --- a/LoopStructural/modelling/features/geological_feature.py +++ b/LoopStructural/modelling/features/geological_feature.py @@ -132,6 +132,7 @@ def evaluate_value(self, evaluation_points): # apply faulting after working out which regions are visible if self.faults_enabled: for f in self.faults: + print(f.name, self.name) evaluation_points = f.apply_to_points(evaluation_points) v[mask] = self.interpolator.evaluate_value(evaluation_points[mask, :]) return v diff --git a/dev/run_m2l_model.py b/dev/run_m2l_model.py index 8df80abfd..c6d4f4efb 100644 --- a/dev/run_m2l_model.py +++ b/dev/run_m2l_model.py @@ -21,12 +21,12 @@ fault_params = {'interpolatortype':'FDI', 'nelements':1e4, - # 'data_region':.2, - 'solver':'lu', + 'data_region':.1000, + 'solver':'pyamg', # overprints:overprints, 'cpw':10, 'npw':10} -foliation_params = {'nelements':1e5, # how many tetras/voxels +foliation_params = {'nelements':1e4, # how many tetras/voxels 'buffer':2.5, # how much to extend nterpolation around box 'solver':'pyamg', 'npw':10, @@ -47,7 +47,11 @@ # print(model.features[1][0].interpolator.support) # print(model.support) view = LavaVuModelViewer(model,vertical_exaggeration=1) -view.add_isosurface(model.features[1][0]) +# for i in range(3):#f in model['supergroup_0'].faults: +# f = model['supergroup_0'].faults[i] +# view.add_vector_field(f,locations=model.regular_grid()[::100,:]) +# # model['supergroup_0'].evaluate_value(model.regular_grid(nsteps=(10,10,10))) +# view.add_isosurface(f,value=0) # # view.interactive() view.add_model_surfaces(faults=True)#filename=filename) # # # view.add_data(model['supergroup_0']) From f130d3f032d32ba3496fcfae1e95e6022b0a8468 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Thu, 4 Feb 2021 17:40:56 +1100 Subject: [PATCH 14/29] (TESTS) added test for base support --- .../interpolator/test_discrete_supports.py | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/unit_tests/interpolator/test_discrete_supports.py b/tests/unit_tests/interpolator/test_discrete_supports.py index 880146ae5..fb26d8cfb 100644 --- a/tests/unit_tests/interpolator/test_discrete_supports.py +++ b/tests/unit_tests/interpolator/test_discrete_supports.py @@ -81,4 +81,29 @@ def test_evaluate_gradient_tetmesh(): grid = TetMesh() vector = np.mean(grid.evaluate_gradient(grid.barycentre(),grid.nodes[:,1]),axis=0) # vector/=np.linalg.norm(vector) - assert np.sum(vector-np.array([0,grid.step_vector[1],0])) == 0 \ No newline at end of file + assert np.sum(vector-np.array([0,grid.step_vector[1],0])) == 0 + +def test_change_origin(): + grid = StructuredGrid(origin=np.zeros(3),nsteps=np.array([5,5,5])) + grid.origin = np.array([-1,-1,-1]) + assert(np.all(grid.origin == np.array([-1,-1,-1]))) + assert (np.all(grid.nsteps == np.array([6,6,6]))) + assert (np.all(grid.step_vector == np.ones(3))) + +def test_change_maximum(): + grid = StructuredGrid(origin=np.zeros(3),nsteps=np.array([5,5,5])) + grid.maximum = np.array([7,7,7]) + assert (np.all(grid.nsteps == np.array([7,7,7]))) + assert (np.all(grid.maximum == np.array([7,7,7]))) + assert (np.all(grid.step_vector == np.ones(3))) + +def test_change_maximum_and_origin(): + grid = StructuredGrid(origin=np.zeros(3),nsteps=np.array([5,5,5])) + grid.origin = np.array([-1.,-1.,-1.]) + assert(np.all(grid.origin == np.array([-1,-1,-1]))) + assert (np.all(grid.nsteps == np.array([6,6,6]))) + assert (np.all(grid.step_vector == np.ones(3))) + grid.maximum = np.array([7.,7.,7.]) + assert (np.all(grid.nsteps == np.array([8,8,8]))) + assert (np.all(grid.maximum == np.array([7.,7.,7.]))) + assert (np.all(grid.step_vector == np.ones(3))) \ No newline at end of file From f6dddd8839e0e120b2501d037005d2d7430b1873 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Thu, 4 Feb 2021 17:41:13 +1100 Subject: [PATCH 15/29] (BUG) remove skimage warning for marching cubes --- LoopStructural/visualisation/model_visualisation.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/LoopStructural/visualisation/model_visualisation.py b/LoopStructural/visualisation/model_visualisation.py index 6f1fe6d1f..41165ebf0 100644 --- a/LoopStructural/visualisation/model_visualisation.py +++ b/LoopStructural/visualisation/model_visualisation.py @@ -13,7 +13,7 @@ except ImportError: logger.error("Please install lavavu: pip install lavavu") import numpy as np -from skimage.measure import marching_cubes_lewiner as marching_cubes +from skimage.measure import marching_cubes from LoopStructural.modelling.features import GeologicalFeature from LoopStructural.utils.helper import create_surface, get_vectors, create_box @@ -310,6 +310,7 @@ def add_isosurface(self, geological_feature, value = None, isovalue=None, self.model.rescale(verts) except (ValueError, RuntimeError) as e: + print(e) logger.warning("Cannot isosurface {} at {}, skipping".format(geological_feature.name,isovalue)) continue @@ -399,6 +400,14 @@ def add_scalar_field(self, geological_feature, name=None, cmap='rainbow', vmin=N vmax = np.nanmax(val) surf.colourmap(cmap, range=(vmin, vmax)) + def add_box(self,bounding_box,name,colour='red'): + points, tri = create_box(bounding_box,self.nsteps) + + surf = self.lv.triangles(name) + surf.vertices(self.model.rescale(points)) + surf.indices(tri) + surf.colours(colour) + def add_model(self, cmap = None, **kwargs): """Add a block model painted by stratigraphic id to the viewer From a07cd7f7251b391ee530e9a21298b654983a125c Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Thu, 4 Feb 2021 17:42:28 +1100 Subject: [PATCH 16/29] (FEATURE) using fault extent to define interpolation geometry Still need to add in a case for when the fault doesn't have a volume --- .../base_structured_3d_support.py | 4 ++-- .../modelling/fault/fault_builder.py | 21 +++++++++++++++---- .../modelling/fault/fault_segment.py | 5 +++-- .../features/geological_feature_builder.py | 2 ++ LoopStructural/utils/map2loop.py | 2 +- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/LoopStructural/interpolators/base_structured_3d_support.py b/LoopStructural/interpolators/base_structured_3d_support.py index ddccf504d..7f5a26c36 100644 --- a/LoopStructural/interpolators/base_structured_3d_support.py +++ b/LoopStructural/interpolators/base_structured_3d_support.py @@ -67,10 +67,10 @@ def maximum(self,maximum): """ update the number of steps to fit new boundary """ - maximum = np.array(maximum) + maximum = np.array(maximum,dtype=float) length = maximum-self.origin length /= self.step_vector - self.nsteps = np.ceil(length).astype(int) + self._nsteps = np.ceil(length).astype(int) @property def n_nodes(self): return np.product(self.nsteps) diff --git a/LoopStructural/modelling/fault/fault_builder.py b/LoopStructural/modelling/fault/fault_builder.py index e9fa47ae3..e30ae2010 100644 --- a/LoopStructural/modelling/fault/fault_builder.py +++ b/LoopStructural/modelling/fault/fault_builder.py @@ -75,12 +75,16 @@ def create_data_from_geometry(self, if vertical_radius is not None: fault_depth[0,:] = fault_center[:3]+slip_vector*vertical_radius fault_depth[1,:] = fault_center[:3]-slip_vector*vertical_radius + # data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = \ + # [fault_depth[0,0],fault_depth[0,1],fault_depth[0,2],self.name,1,1] + # data.loc[len(data),['X','Y','Z','feature_name','val','coord']] = \ + # [fault_depth[1,0],fault_depth[1,1],fault_depth[1,2],self.name,-1,1] self.update_geometry(fault_depth) #TODO need to add data here data.loc[len(data),['X','Y','Z','feature_name','nx','ny','nz','coord']] =\ [fault_center[0],fault_center[1],fault_center[2],self.name,slip_vector[0],slip_vector[1],slip_vector[2],1] # add strike vector to constraint fault extent - data.loc[len(data),['X','Y','Z','feature_name','nx','ny','nz','coord']] = [fault_center[0],fault_center[1],fault_center[2],\ + data.loc[len(data),['X','Y','Z','feature_name','gx','gy','gz','coord']] = [fault_center[0],fault_center[1],fault_center[2],\ self.name, strike_vector[0], strike_vector[1], strike_vector[2], 2] self.add_data_from_data_frame(data) def set_mesh_geometry(self,buffer): @@ -92,10 +96,16 @@ def set_mesh_geometry(self,buffer): percentage of length to add to edges """ length = self.maximum-self.origin - + # origin = self.builders[0].interpolator.support.origin + # maximum = self.builders[0].interpolator.support.maximum#set_interpolation_geometry + # if origin[2]>self.origin[2]: + # origin[2]=self.origin[2] + # if maximum[2] Date: Thu, 4 Feb 2021 17:43:14 +1100 Subject: [PATCH 17/29] (TESTS) trying to profile/test different solvers --- .gitignore | 3 +- dev/Untitled.ipynb | 6519 ++++++++++++++++++++++ dev/run_m2l_model.py | 54 +- dev/solver time estimate iterative.ipynb | 4362 +++++++++++++++ dev/solver time estimate.ipynb | 2976 ++++++++++ dev/solver_diagnostic.py | 67 + dev/solver_diagnostic.txt | 1163 ++++ dev/solver_diagnostics.py | 655 +++ 8 files changed, 15772 insertions(+), 27 deletions(-) create mode 100644 dev/Untitled.ipynb create mode 100644 dev/solver time estimate iterative.ipynb create mode 100644 dev/solver time estimate.ipynb create mode 100644 dev/solver_diagnostic.py create mode 100644 dev/solver_diagnostic.txt create mode 100644 dev/solver_diagnostics.py diff --git a/.gitignore b/.gitignore index 4495acc14..3e6b6effd 100644 --- a/.gitignore +++ b/.gitignore @@ -128,4 +128,5 @@ docs/source/auto_examples/* examples/*/*.png docs/source/test/* examples/*.png -dev/unconf/* \ No newline at end of file +dev/unconf/* +dev/scalar_field \ No newline at end of file diff --git a/dev/Untitled.ipynb b/dev/Untitled.ipynb new file mode 100644 index 000000000..84e9961a7 --- /dev/null +++ b/dev/Untitled.ipynb @@ -0,0 +1,6519 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "requested-pricing", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext snakeviz" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "missing-rwanda", + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "from LoopStructural import GeologicalModel\n", + "from LoopStructural.visualisation import LavaVuModelViewer\n", + "from LoopStructural import GeologicalModel\n", + "from LoopStructural.utils import log_to_file\n", + "import numpy as np\n", + "# log_to_file('dev/ls.log')\n", + "\n", + "\n", + "fault_params = {'interpolatortype':'FDI',\n", + " 'nelements':1e4,\n", + "# 'data_region':.1000, \n", + " 'solver':'pyamg',\n", + " 'damp':True,\n", + "# overprints:overprints,\n", + " 'cpw':10,\n", + " 'npw':10}\n", + "foliation_params = {'nelements':1e5, # how many tetras/voxels\n", + " 'buffer':2.5, # how much to extend nterpolation around box\n", + " 'solver':'pyamg',\n", + " 'npw':10,\n", + " 'cpw':10,\n", + " 'interpolatortype':'FDI',\n", + " 'damp':True}\n", + "\n", + "model, m2l_data = GeologicalModel.from_map2loop_directory('unconf',\n", + " skip_faults=False,\n", + " rescale=False,\n", + " fault_params=fault_params,\n", + " foliation_params=foliation_params)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "funny-history", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 0%| | 0/13 [00:00,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# %%snakeviz\n", + "# model['supergroup_0'].builder.update()\n", + "model['supergroup_0'].faults" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "cathedral-delta", + "metadata": {}, + "outputs": [], + "source": [ + "model['Fault_2843'][0].builder.update()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "suitable-printer", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fault_2997 supergroup_1\n", + "Fault_16769 supergroup_1\n", + "Fault_15552 supergroup_1\n", + "Fault_14378 supergroup_1\n", + "Fault_12660 supergroup_1\n", + "Fault_12658 supergroup_1\n", + "Fault_12647 supergroup_1\n", + "Fault_3498 supergroup_1\n", + "Fault_3496 supergroup_1\n", + "Fault_2843 supergroup_1\n", + "Fault_2248 supergroup_1\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/lgrose/dev/python/LoopStructural/LoopStructural/visualisation/model_visualisation.py:301: RuntimeWarning: All-NaN slice encountered\n", + " if isovalue > np.nanmax(val) or isovalue < np.nanmin(val):\n", + "2021-02-04 17:39:53,208 ~ LoopStructural.visualisation.model_visualisation ~ WARNING ~ Cannot isosurface Fault_2843 at 0, skipping\n", + "2021-02-04 17:39:53,208 ~ LoopStructural.visualisation.model_visualisation ~ WARNING ~ Cannot isosurface Fault_2843 at 0, skipping\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "No surface found at the given iso value.\n", + "Fault_2997 supergroup_1\n", + "Fault_16769 supergroup_1\n", + "Fault_15552 supergroup_1\n", + "Fault_14378 supergroup_1\n", + "Fault_12660 supergroup_1\n", + "Fault_12658 supergroup_1\n", + "Fault_12647 supergroup_1\n", + "Fault_3498 supergroup_1\n", + "Fault_3496 supergroup_1\n", + "Fault_2843 supergroup_1\n", + "Fault_2248 supergroup_1\n", + "Fault_2997 supergroup_1\n", + "Fault_16769 supergroup_1\n", + "Fault_15552 supergroup_1\n", + "Fault_14378 supergroup_1\n", + "Fault_12660 supergroup_1\n", + "Fault_12658 supergroup_1\n", + "Fault_12647 supergroup_1\n", + "Fault_3498 supergroup_1\n", + "Fault_3496 supergroup_1\n", + "Fault_2843 supergroup_1\n", + "Fault_2248 supergroup_1\n", + "Fault_2997 supergroup_1\n", + "Fault_16769 supergroup_1\n", + "Fault_15552 supergroup_1\n", + "Fault_14378 supergroup_1\n", + "Fault_12660 supergroup_1\n", + "Fault_12658 supergroup_1\n", + "Fault_12647 supergroup_1\n", + "Fault_3498 supergroup_1\n", + "Fault_3496 supergroup_1\n", + "Fault_2843 supergroup_1\n", + "Fault_2248 supergroup_1\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n", + "Fault_2997 supergroup_0\n", + "Fault_16769 supergroup_0\n", + "Fault_15552 supergroup_0\n", + "Fault_14378 supergroup_0\n", + "Fault_12660 supergroup_0\n", + "Fault_12658 supergroup_0\n", + "Fault_12647 supergroup_0\n", + "Fault_3498 supergroup_0\n", + "Fault_3496 supergroup_0\n", + "Fault_2843 supergroup_0\n", + "Fault_2248 supergroup_0\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + " \n", + "
\n", + "
\n", + "

Objects:

\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "view = LavaVuModelViewer(model,vertical_exaggeration=1) \n", + "\n", + "view.nsteps=np.array([70,70,70])\n", + "view.add_scalar_field(model['Fault_2843'][0])\n", + "view.add_isosurface(model['Fault_2843'][0],value=0)\n", + "view.add_model_surfaces()#isosurface(model['supergroup_0'].faults[0][0])\n", + "# view.add_box(view.bounding_box,'box')#scalar_field(None)\n", + "view.nelements=1e6\n", + "view.add_model()\n", + "view.interactive()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "meaningful-stuff", + "metadata": {}, + "outputs": [], + "source": [ + "view.add_fault_displacements()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "furnished-crowd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([ 111., 185., 3122., 3219., 47427., 3178., 2967., 1952.,\n", + " 251., 88.]),\n", + " array([-107383.82498131, -85075.47894794, -62767.13291457,\n", + " -40458.7868812 , -18150.44084782, 4157.90518555,\n", + " 26466.25121892, 48774.59725229, 71082.94328566,\n", + " 93391.28931903, 115699.6353524 ]),\n", + " )" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.hist(model.evaluate_fault_displacements(model.regular_grid(shuffle=False),scale=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "tribal-dancing", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + " \n", + "
\n", + "
\n", + "

Objects:

\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "view2 = LavaVuModelViewer(model)\n", + "# pts = model.regular_grid(shuffle=False)\n", + "# # # view2.add_points(pts,'no fault')\n", + "# for f in model['supergroup_0'].faults:\n", + "# # view2.add_data(f[0],cmap='rainbow',vmin=-1,vmax=1)#add_vector_field(f[1],locations=model.regular_grid()[::100])\n", + "# pts = f.apply_to_points(pts)\n", + "# view2.add_value_data(pts,pts[:,2],'fault',cmap='rainbow',vmin=np.nanmin(pts[:,2]),vmax=np.nanmax(pts[:,2]))\n", + "# # view2.nelements=1e6\n", + "# # view2.add_model()\n", + "view2.add_isosurface(model['Fault_2843'][0],value=0)\n", + "\n", + "view2.interactive()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "noticed-optimum", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 4.84734597e-01, 1.35214858e-03, 6.08859841e-02,\n", + " 0.00000000e+00],\n", + " [ 4.84340045e-01, 2.05276561e-03, 6.08859841e-02,\n", + " 0.00000000e+00],\n", + " [ 4.78286983e-01, 1.07108300e-02, 6.07868482e-02,\n", + " 0.00000000e+00],\n", + " [ 4.71179981e-01, 1.85339282e-02, 6.09190294e-02,\n", + " 0.00000000e+00],\n", + " [ 4.63120015e-01, 2.49942922e-02, 6.09025067e-02,\n", + " 0.00000000e+00],\n", + " [ 4.53584151e-01, 3.05128788e-02, 6.09520747e-02,\n", + " 0.00000000e+00],\n", + " [ 4.44463895e-01, 3.49823030e-02, 6.11668692e-02,\n", + " 0.00000000e+00],\n", + " [ 4.35126700e-01, 3.79727065e-02, 6.10512106e-02,\n", + " 0.00000000e+00],\n", + " [ 4.26417603e-01, 4.05419894e-02, 6.10181653e-02,\n", + " 0.00000000e+00],\n", + " [ 4.19596978e-01, 4.23678983e-02, 6.10346880e-02,\n", + " 0.00000000e+00],\n", + " [ 4.03117385e-01, 4.61431075e-02, 6.15468903e-02,\n", + " 0.00000000e+00],\n", + " [ 4.65267023e-01, 5.18840012e-02, 6.10136592e-02,\n", + " 1.00000000e+00],\n", + " [ 4.37272674e-01, 8.73243926e-04, 6.10136592e-02,\n", + " -1.00000000e+00]])" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + " model['Fault_2997'][0].interpolator.get_value_constraints()[:,:4]\n", + " #- np.array([[ 4.84734597e-01, 1.35214858e-03, 6.08859841e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.84340045e-01, 2.05276561e-03, 6.08859841e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.78286983e-01, 1.07108300e-02, 6.07868482e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.71179981e-01, 1.85339282e-02, 6.09190294e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.63120015e-01, 2.49942922e-02, 6.09025067e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.53584151e-01, 3.05128788e-02, 6.09520747e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.44463895e-01, 3.49823030e-02, 6.11668692e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.35126700e-01, 3.79727065e-02, 6.10512106e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.26417603e-01, 4.05419894e-02, 6.10181653e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.19596978e-01, 4.23678983e-02, 6.10346880e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.03117385e-01, 4.61431075e-02, 6.15468903e-02,\n", + "# 0.00000000e+00, 1.00000000e+00],\n", + "# [ 4.65267023e-01, 5.18840012e-02, 6.10136592e-02,\n", + "# 1.00000000e+00, 1.00000000e+00],\n", + "# [ 4.37272674e-01, 8.73243926e-04, 6.10136592e-02,\n", + "# -1.00000000e+00, 1.00000000e+00]])" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "conditional-private", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-1.652265511293771e-05\n", + "-0.005849019909979949\n", + "-0.006079208560422475\n", + "-0.002147945164681902\n", + "-0.0016026975459549576\n", + "-0.00019827186135525248\n", + "-1.652265511293771e-05\n", + "-0.0011731085130185772\n", + "-6.609062045175083e-05\n", + "-0.012100282978915215\n", + "-0.0007600421351951345\n" + ] + } + ], + "source": [ + "for f in model['supergroup_0'].faults:\n", + " print(f.displacement)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "contrary-wallpaper", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "196" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model['supergroup_0'].faults[0][0].interpolator.nx" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "otherwise-turtle", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 28, 56, ..., 67, 95, 123],\n", + " [ 1, 29, 57, ..., 68, 96, 124],\n", + " [ 2, 30, 58, ..., 69, 97, 125],\n", + " ...,\n", + " [ 70, 98, 126, ..., 137, 165, 193],\n", + " [ 71, 99, 127, ..., 138, 166, 194],\n", + " [ 72, 100, 128, ..., 139, 167, 195]])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model['supergroup_0'].faults[0][0].interpolator.support.neighbour_global_indexes()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "meaningful-barrel", + "metadata": {}, + "outputs": [], + "source": [ + "from LoopStructural.interpolators.operator import Operator\n", + "support = model['supergroup_0'].faults[0][0].interpolator.support\n", + "operator = Operator.Dyy_mask\n", + "region = model['supergroup_0'].faults[0][0].interpolator.region\n", + "nx = model['supergroup_0'].faults[0][0].interpolator.nx" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "transparent-carrier", + "metadata": {}, + "outputs": [], + "source": [ + "global_indexes = support.neighbour_global_indexes() # np.array([ii,jj]))\n", + "\n", + "a = np.tile(operator.flatten(), (global_indexes.shape[1], 1))\n", + "idc = global_indexes.T\n", + "\n", + "gi = np.zeros(support.n_nodes)\n", + "gi[:] = -1\n", + "gi[region] = np.arange(0, nx)\n", + "idc = gi[idc]\n", + "inside = ~np.any(idc == -1, axis=1)\n", + "B = np.zeros(global_indexes.shape[1])" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "streaming-architecture", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0., 1., 2., ..., 70., 71., 72.],\n", + " [ 28., 29., 30., ..., 98., 99., 100.],\n", + " [ 56., 57., 58., ..., 126., 127., 128.],\n", + " ...,\n", + " [ 67., 68., 69., ..., 137., 138., 139.],\n", + " [ 95., 96., 97., ..., 165., 166., 167.],\n", + " [123., 124., 125., ..., 193., 194., 195.]])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "idc" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "smaller-casting", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-0.01020215 -0.00559887 -0.01163749]\n", + "[0.02992316 0.01963919 0.0141344 ]\n", + "[-0.0126735 -0.00633675 -0.01302676]\n", + "[0.02304497 0.01152249 0.01915912]\n", + "[-0.01101461 -0.0055073 -0.01215842]\n", + "[0.02098615 0.02064642 0.02871092]\n", + "[-0.0210293 -0.0258364 -0.03331293]\n", + "[0.03266469 0.04070658 0.03969158]\n", + "[-0.02271429 -0.01135714 -0.02455212]\n", + "[0.03443647 0.01721823 0.03452699]\n", + "[-0.01435223 -0.02870446 -0.03139314]\n", + "[0.02488568 0.02946468 0.04050254]\n", + "[-0.00874653 -0.01152593 -0.01446889]\n", + "[0.0256283 0.01536162 0.0236024 ]\n", + "[-0.01296546 -0.01671901 -0.02115723]\n", + "[0.01983343 0.01915776 0.03125738]\n", + "[-0.00755551 -0.01234042 -0.01446968]\n", + "[0.01842286 0.02670891 0.02359372]\n", + "[-0.01732074 -0.01690146 -0.02420057]\n", + "[0.03284539 0.01715088 0.03839411]\n", + "[-0.01001662 -0.01147702 -0.01523334]\n", + "[0.01165734 0.01589966 0.0355002 ]\n" + ] + } + ], + "source": [ + "for f in model['supergroup_0'].faults:\n", + " print(f[0].interpolator.support.origin - f.builder.origin)#\n", + " print(f[0].interpolator.support.maximum-f.builder.maximum)#vbb = np.zeros((2,3))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "outside-valuation", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'supergroup_1': {'Turee_Creek_Group': {'max': 0,\n", + " 'min': -2409.0,\n", + " 'id': 0,\n", + " 'colour': '#E0CABF'}},\n", + " 'supergroup_0': {'Boolgeeda_Iron_Formation': {'max': 0,\n", + " 'min': -400.0,\n", + " 'id': 1,\n", + " 'colour': '#B5E1FC'},\n", + " 'Woongarra_Rhyolite': {'max': -400.0,\n", + " 'min': -641.0,\n", + " 'id': 2,\n", + " 'colour': '#CAA894'},\n", + " 'Weeli_Wolli_Formation': {'max': -641.0,\n", + " 'min': -831.0,\n", + " 'id': 3,\n", + " 'colour': '#E0CABF'},\n", + " 'Brockman_Iron_Formation': {'max': -831.0,\n", + " 'min': -1248.0,\n", + " 'id': 4,\n", + " 'colour': '#84CDFA'},\n", + " 'Mount_McRae_Shale_and_Mount_Sylvia_Formation': {'max': -1248.0,\n", + " 'min': -1323.0,\n", + " 'id': 5,\n", + " 'colour': '#B6846A'},\n", + " 'Wittenoom_Formation': {'max': -1323.0,\n", + " 'min': -1601.0,\n", + " 'id': 6,\n", + " 'colour': '#E0CABF'},\n", + " 'Marra_Mamba_Iron_Formation': {'max': -1601.0,\n", + " 'min': -1709.0,\n", + " 'id': 7,\n", + " 'colour': '#B5E1FC'},\n", + " 'Jeerinah_Formation': {'max': -1709.0,\n", + " 'min': -2175.0,\n", + " 'id': 8,\n", + " 'colour': '#CDCFA7'},\n", + " 'Fortescue_Group': {'max': -2175.0,\n", + " 'min': -2453.0,\n", + " 'id': 9,\n", + " 'colour': '#8EE4B4'},\n", + " 'Bunjinah_Formation': {'max': -2453.0,\n", + " 'min': -2731.0,\n", + " 'id': 10,\n", + " 'colour': '#E6E7D3'},\n", + " 'Pyradie_Formation': {'max': -2731.0,\n", + " 'min': -3009.0,\n", + " 'id': 11,\n", + " 'colour': '#D5D7B6'}},\n", + " 'faults': {'Fault_2248': {'FaultCenter': array([0.17383077, 0.29932709, 0.06272551]),\n", + " 'FaultDipDirection': 48.887019958523695,\n", + " 'InfluenceDistance': array([2304.9164201]),\n", + " 'HorizontalRadius': array([4609.83284019]),\n", + " 'VerticalRadius': array([4609.83284019]),\n", + " 'colour': array(['#442082'], dtype=object)},\n", + " 'Fault_2843': {'FaultCenter': array([0.07724244, 0.06862401, 0.06150118]),\n", + " 'FaultDipDirection': 44.29804963234955,\n", + " 'InfluenceDistance': array([3661.72473377]),\n", + " 'HorizontalRadius': array([7323.44946754]),\n", + " 'VerticalRadius': array([7323.44946754]),\n", + " 'colour': array(['#3cfde6'], dtype=object)},\n", + " 'Fault_3496': {'FaultCenter': array([0.23350732, 0.06478016, 0.06196436]),\n", + " 'FaultDipDirection': 58.522656379469424,\n", + " 'InfluenceDistance': array([2189.36965102]),\n", + " 'HorizontalRadius': array([4378.73930205]),\n", + " 'VerticalRadius': array([4378.73930205]),\n", + " 'colour': array(['#30f90e'], dtype=object)},\n", + " 'Fault_3498': {'FaultCenter': array([0.37057632, 0.09021479, 0.06242507]),\n", + " 'FaultDipDirection': 52.20670462480766,\n", + " 'InfluenceDistance': array([3201.24612359]),\n", + " 'HorizontalRadius': array([6402.49224719]),\n", + " 'VerticalRadius': array([6402.49224719]),\n", + " 'colour': array(['#c7dd01'], dtype=object)},\n", + " 'Fault_12647': {'FaultCenter': array([0.21195948, 0.04807319, 0.06151935]),\n", + " 'FaultDipDirection': 52.80670163665004,\n", + " 'InfluenceDistance': array([2189.25031637]),\n", + " 'HorizontalRadius': array([4378.50063274]),\n", + " 'VerticalRadius': array([4378.50063274]),\n", + " 'colour': array(['#e48875'], dtype=object)},\n", + " 'Fault_12658': {'FaultCenter': array([0.64555179, 0.16313155, 0.06215162]),\n", + " 'FaultDipDirection': -113.88578381648401,\n", + " 'InfluenceDistance': array([4750.01453417]),\n", + " 'HorizontalRadius': array([9500.02906834]),\n", + " 'VerticalRadius': array([9500.02906834]),\n", + " 'colour': array(['#34a20f'], dtype=object)},\n", + " 'Fault_12660': {'FaultCenter': array([0.0777325 , 0.24044021, 0.06221675]),\n", + " 'FaultDipDirection': -157.69033035511146,\n", + " 'InfluenceDistance': array([3714.9177542]),\n", + " 'HorizontalRadius': array([7429.83550841]),\n", + " 'VerticalRadius': array([7429.83550841]),\n", + " 'colour': array(['#0b0d04'], dtype=object)},\n", + " 'Fault_14378': {'FaultCenter': array([0.10416902, 0.11186181, 0.061469 ]),\n", + " 'FaultDipDirection': -129.14354055965515,\n", + " 'InfluenceDistance': array([5040.49248328]),\n", + " 'HorizontalRadius': array([10080.98496655]),\n", + " 'VerticalRadius': array([10080.98496655]),\n", + " 'colour': array(['#c36ed8'], dtype=object)},\n", + " 'Fault_15552': {'FaultCenter': array([0.04264652, 0.23891892, 0.06191865]),\n", + " 'FaultDipDirection': -154.94807562307528,\n", + " 'InfluenceDistance': array([1839.6584928]),\n", + " 'HorizontalRadius': array([3679.3169856]),\n", + " 'VerticalRadius': array([3679.3169856]),\n", + " 'colour': array(['#0e71e0'], dtype=object)},\n", + " 'Fault_16769': {'FaultCenter': array([0.1563481 , 0.27926162, 0.06230858]),\n", + " 'FaultDipDirection': -166.62626730380896,\n", + " 'InfluenceDistance': array([1971.04566316]),\n", + " 'HorizontalRadius': array([3942.09132632]),\n", + " 'VerticalRadius': array([3942.09132632]),\n", + " 'colour': array(['#fd77b0'], dtype=object)},\n", + " 'Fault_2997': {'FaultCenter': array([0.45126985, 0.02637862, 0.06101366]),\n", + " 'FaultDipDirection': 28.75767431749918,\n", + " 'InfluenceDistance': array([1760.83878406]),\n", + " 'HorizontalRadius': array([3521.67756813]),\n", + " 'VerticalRadius': array([3521.67756813]),\n", + " 'colour': array(['#f1c26b'], dtype=object)}}}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.stratigraphic_column" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "hungarian-flexibility", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/dev/run_m2l_model.py b/dev/run_m2l_model.py index c6d4f4efb..aec6af986 100644 --- a/dev/run_m2l_model.py +++ b/dev/run_m2l_model.py @@ -4,23 +4,10 @@ from LoopStructural.utils import log_to_file import numpy as np # log_to_file('dev/ls.log') -fault_params = {'interpolatortype':'FDI', - 'nelements':1e4, - # 'data_region':0, - 'solver':'pyamg', - 'step':10, - 'cpw':10, - 'npw':10, - 'tol':1e-8 - } -foliation_params = {'interpolatortype':'FDI' , # 'interpolatortype':'PLI', - 'nelements':1e4, # how many tetras/voxels - 'data_region':.3, # how much to extend nterpolation around box - 'solver':'pyamg', - 'damp':True} + fault_params = {'interpolatortype':'FDI', - 'nelements':1e4, + 'nelements':1e3, 'data_region':.1000, 'solver':'pyamg', # overprints:overprints, @@ -36,9 +23,16 @@ model, m2l_data = GeologicalModel.from_map2loop_directory('./dev/unconf', skip_faults=False, - # rescale=False, + rescale=False, fault_params=fault_params, foliation_params=foliation_params) +view = LavaVuModelViewer(model,vertical_exaggeration=1) +for f in model['supergroup_0'].faults: + bb = np.zeros((3,2)) + bb[:,0] = f.builder.origin + bb[:,1] = f.builder.maximum + view.add_box(bb,f.name+'_support') +view.interactive() # print(model.data[model.data['coord']==1]) # # print(model.features[1][0].builder.data) # for f in features: @@ -46,14 +40,22 @@ # model.features[1][0].builder.update()#evaluate_value(np.array([[0,0,0]])) # print(model.features[1][0].interpolator.support) # print(model.support) -view = LavaVuModelViewer(model,vertical_exaggeration=1) -# for i in range(3):#f in model['supergroup_0'].faults: -# f = model['supergroup_0'].faults[i] -# view.add_vector_field(f,locations=model.regular_grid()[::100,:]) -# # model['supergroup_0'].evaluate_value(model.regular_grid(nsteps=(10,10,10))) -# view.add_isosurface(f,value=0) +# print(model['supergroup_0'].faults[0][0].builder.build_arguments) +# model['supergroup_0'].faults[0][0].builder.update() +# print(model) +# for f in model['supergroup_0'].faults: +# print(f[0].interpolator.nx) +# view = LavaVuModelViewer(model,vertical_exaggeration=1) +# # for i in range(3): +# # view.add_isosurface(model['supergroup_0'].faults[i][0],value=0) # # view.interactive() -view.add_model_surfaces(faults=True)#filename=filename) -# # # view.add_data(model['supergroup_0']) -# view.add_fault_displacements() -view.interactive() \ No newline at end of file +# # for f in model['supergroup_0'].faults:' +# # # f = model['supergroup_0'].faults[i] +# # view.add_vector_field(f,locations=model.regular_grid()[::100,:]) +# # # # model['supergroup_0'].evaluate_value(model.regular_grid(nsteps=(10,10,10))) +# # view.add_isosurface(f,value=0) +# # # # view.interactive() +# view.add_model_surfaces()#filename=filename) +# # # # # view.add_data(model['supergroup_0']) +# # # view.add_fault_displacements() +# view.interactive() \ No newline at end of file diff --git a/dev/solver time estimate iterative.ipynb b/dev/solver time estimate iterative.ipynb new file mode 100644 index 000000000..2370d9221 --- /dev/null +++ b/dev/solver time estimate iterative.ipynb @@ -0,0 +1,4362 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "noted-overview", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2021-02-04 13:36:03,817 ~ LoopStructural.modelling.core.geological_model ~ WARNING ~ Cannot import Surfe\n" + ] + } + ], + "source": [ + "#import required \n", + "from LoopStructural import GeologicalModel\n", + "from LoopStructural.datasets import load_claudius\n", + "from LoopStructural.visualisation import LavaVuModelViewer\n", + "from scipy.spatial.transform import Rotation as R\n", + "from scipy.ndimage.interpolation import rotate\n", + "import pyamg\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "complimentary-conservation", + "metadata": {}, + "outputs": [], + "source": [ + "data, bb = load_claudius() # load data\n" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "meaningful-chicago", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2021-02-04 14:00:36,724 ~ LoopStructural.modelling.core.geological_model ~ WARNING ~ No data for , skipping\n", + "2021-02-04 14:00:36,724 ~ LoopStructural.modelling.core.geological_model ~ WARNING ~ No data for , skipping\n" + ] + } + ], + "source": [ + "model = GeologicalModel(bb[0,:],bb[1,:],rescale=False)\n", + "model.set_model_data(data)\n", + "strati = model.create_and_add_foliation(' ',nelements=1e6,solver='fake',interpolatortype='FDI')" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "female-panel", + "metadata": {}, + "outputs": [], + "source": [ + "from solver_diagnostics import solver_diagnostics" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "available-export", + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'interpolator'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mB\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstrati\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterpolator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuild_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'interpolator'" + ] + } + ], + "source": [ + "A,B = strati.interpolator.build_matrix()" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "straight-being", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Searching for optimal smoothed aggregation method for (1015000,1015000) matrix\n", + " ...\n", + " Detected a hermitian matrix\n", + " Detected positive definiteness\n", + " ...\n", + " Test 1 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None]\n", + " Test 2 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 3 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 4 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 5 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 6 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 7 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 8 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 9 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 10 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 11 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 12 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 13 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 14 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 15 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 16 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 17 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 18 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 19 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 20 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 21 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 22 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 23 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 24 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 25 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 26 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 27 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 28 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 29 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 30 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 31 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 32 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 33 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 34 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 35 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 36 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 37 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 38 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 39 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 40 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 41 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 42 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 43 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 44 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 45 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 46 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 47 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 48 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 49 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 50 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 51 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 52 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 53 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 54 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 55 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 56 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 57 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 58 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 59 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 60 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " ...\n", + " --> Diagnostic Results located in solver_diagnostic.txt\n", + " ...\n", + " --> See automatically generated function definition\n", + " ./solver_diagnostic.py.\n", + "\n", + " Use the function defined here to generate and run the best\n", + " smoothed aggregation method found. The only argument taken\n", + " is a CSR/BSR matrix.\n", + "\n", + " To run: >>> # User must load/generate CSR/BSR matrix A\n", + " >>> from solver_diagnostic import solver_diagnostic\n", + " >>> solver_diagnostic(A)\n" + ] + } + ], + "source": [ + "solver_diagnostics(A,B_list=[(B,None,'test')])" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "loved-system", + "metadata": {}, + "outputs": [], + "source": [ + "from pyamg import gallery\n", + "A = gallery.gauge_laplacian( 100)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "chicken-liabilities", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "matrix([[ 4. +0.j , -0.95759664+0.28811225j,\n", + " 0. +0.j , ..., 0. +0.j ,\n", + " 0. +0.j , 0. +0.j ],\n", + " [-0.95759664-0.28811225j, 4. +0.j ,\n", + " -0.67245823+0.74013508j, ..., 0. +0.j ,\n", + " 0. +0.j , 0. +0.j ],\n", + " [ 0. +0.j , -0.67245823-0.74013508j,\n", + " 4. +0.j , ..., 0. +0.j ,\n", + " 0. +0.j , 0. +0.j ],\n", + " ...,\n", + " [ 0. +0.j , 0. +0.j ,\n", + " 0. +0.j , ..., 4. +0.j ,\n", + " -0.68431557+0.72918599j, 0. +0.j ],\n", + " [ 0. +0.j , 0. +0.j ,\n", + " 0. +0.j , ..., -0.68431557-0.72918599j,\n", + " 4. +0.j , -0.87569732-0.48286043j],\n", + " [ 0. +0.j , 0. +0.j ,\n", + " 0. +0.j , ..., 0. +0.j ,\n", + " -0.87569732+0.48286043j, 4. +0.j ]])" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A.todense()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "three-extent", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 20/20 [36:35<00:00, 109.80s/it]\n", + " 90%|█████████ | 18/20 [2:57:52<19:45, 592.92s/it] \n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;31m# nelements=1e4\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mstrati\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_and_add_foliation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'strati'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mnelements\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0msolver\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msolver\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0minterpolatortype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'FDI'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0mstrati\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuilder\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m \u001b[0mresults\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msolver\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'time'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mstart\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0mresults\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msolver\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'nx'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstrati\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterpolator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/modelling/features/geological_feature_builder.py\u001b[0m in \u001b[0;36mupdate\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 77\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 78\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuild\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuild_arguments\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 79\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mproperty\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 80\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/modelling/features/geological_feature_builder.py\u001b[0m in \u001b[0;36mbuild\u001b[0;34m(self, fold, fold_weights, data_region, **kwargs)\u001b[0m\n\u001b[1;32m 409\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'cgw'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0.0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 410\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterpolator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msetup_interpolator\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 411\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterpolator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msolve_system\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 412\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_up_to_date\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 413\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_feature\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/interpolators/geological_interpolator.py\u001b[0m in \u001b[0;36msolve_system\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 177\u001b[0m \u001b[0mSolves\u001b[0m \u001b[0mthe\u001b[0m \u001b[0minterpolation\u001b[0m \u001b[0mequations\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 178\u001b[0m \"\"\"\n\u001b[0;32m--> 179\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_solve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 180\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mup_to_date\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 181\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/interpolators/discrete_interpolator.py\u001b[0m in \u001b[0;36m_solve\u001b[0;34m(self, solver, **kwargs)\u001b[0m\n\u001b[1;32m 500\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msolver\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'cg'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 501\u001b[0m \u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minfo\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Solving using conjugate gradient\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 502\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mregion\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_solve_cg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mB\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 503\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msolver\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'chol'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 504\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mregion\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_solve_chol\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mB\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/interpolators/discrete_interpolator.py\u001b[0m in \u001b[0;36m_solve_cg\u001b[0;34m(self, A, B, precon, **kwargs)\u001b[0m\n\u001b[1;32m 446\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mprecon\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 447\u001b[0m \u001b[0mcgargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'M'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mprecon\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 448\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msla\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mB\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mcgargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnx\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 449\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 450\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_solve_pyamg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mB\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtol\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1e-8\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mx0\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/isolve/iterative.py\u001b[0m in \u001b[0;36mcg\u001b[0;34m(A, b, x0, tol, maxiter, M, callback, atol)\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/_lib/_threadsafety.py\u001b[0m in \u001b[0;36mcaller\u001b[0;34m(func, *a, **kw)\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcaller\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 43\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 44\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 45\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mscipy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_lib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecorator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecorate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcaller\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 46\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/isolve/iterative.py\u001b[0m in \u001b[0;36mcg\u001b[0;34m(A, b, x0, tol, maxiter, M, callback, atol)\u001b[0m\n\u001b[1;32m 327\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mijob\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 328\u001b[0m \u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m*=\u001b[0m \u001b[0msclr2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 329\u001b[0;31m \u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0msclr1\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mmatvec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 330\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mijob\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 331\u001b[0m \u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpsolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/interface.py\u001b[0m in \u001b[0;36mmatvec\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 230\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'dimension mismatch'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 231\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 232\u001b[0;31m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_matvec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 233\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 234\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatrix\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/interface.py\u001b[0m in \u001b[0;36m_matvec\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 197\u001b[0m \u001b[0mwill\u001b[0m \u001b[0mdefine\u001b[0m \u001b[0mmatrix\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mvector\u001b[0m \u001b[0mmultiplication\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mwell\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 198\u001b[0m \"\"\"\n\u001b[0;32m--> 199\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatmat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 200\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 201\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmatvec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/interface.py\u001b[0m in \u001b[0;36mmatmat\u001b[0;34m(self, X)\u001b[0m\n\u001b[1;32m 335\u001b[0m % (self.shape, X.shape))\n\u001b[1;32m 336\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 337\u001b[0;31m \u001b[0mY\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_matmat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 338\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 339\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mY\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatrix\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/interface.py\u001b[0m in \u001b[0;36m_matmat\u001b[0;34m(self, X)\u001b[0m\n\u001b[1;32m 729\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 730\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_matmat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 731\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 732\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 733\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_adjoint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/base.py\u001b[0m in \u001b[0;36mdot\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 357\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 358\u001b[0m \"\"\"\n\u001b[0;32m--> 359\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 360\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 361\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mpower\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/base.py\u001b[0m in \u001b[0;36m__mul__\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 467\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_mul_vector\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 468\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mN\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 469\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_mul_vector\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mravel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mM\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 470\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndim\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m2\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mN\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 471\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_mul_multivector\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/compressed.py\u001b[0m in \u001b[0;36m_mul_vector\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 474\u001b[0m \u001b[0;31m# csr_matvec or csc_matvec\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 475\u001b[0m \u001b[0mfn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_sparsetools\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_matvec'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 476\u001b[0;31m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mM\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mN\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindptr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindices\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 477\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 478\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "import time\n", + "from tqdm import tqdm\n", + "\n", + "results= {}\n", + "for solver in ['pyamg','cg','lsqr']:\n", + " results[solver] = {'nx':[],'nel':[],'time':[],'c':[]}\n", + " for nel in tqdm(np.arange(1e3,1e6,5e4)):\n", + " start = time.time()\n", + "# solver = 'pyamg'\n", + " # nelements=1e4\n", + " strati = model.create_and_add_foliation('strati',nelements=nel,solver=solver,interpolatortype='FDI')\n", + " strati.builder.update()\n", + " results[solver]['time'].append(time.time()-start)\n", + " results[solver]['nx'].append(strati.interpolator.nx)\n", + " results[solver]['nel'].append(nel)\n", + " np.save('scalar_field/{}_{}.npy'.format(solver,nel),strati.interpolator.c)\n", + "# results[solver]['c'].append(strati.interpolator.c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "opposite-escape", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "waiting-uganda", + "metadata": {}, + "outputs": [], + "source": [ + "import pyamg\n", + "def solve(A,B):\n", + " print(tol)\n", + " return pyamg.solve(A, B, tol=tol, verb=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "separated-million", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 0%| | 0/100 [00:00" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for solver in results.keys():\n", + " plt.scatter(results[solver]['nel'],(results[solver]['nx']),label=solver)\n", + "plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "accomplished-account", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, '$log_e(time)$')" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for solver in results.keys():\n", + " plt.scatter(results[solver]['nel'],np.log(results[solver]['time']),label=solver)\n", + "plt.legend()\n", + "plt.xlabel('Number of elements')\n", + "plt.ylabel(r'$log_e(time)$')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "understanding-cincinnati", + "metadata": {}, + "outputs": [], + "source": [ + "for solver in results.keys():\n", + " plt.scatter(results[solver]['nel'],(results[solver]['time']),label=solver)\n", + "plt.legend()\n", + "plt.xlabel('Number of elements')\n", + "plt.ylabel(r'$log_e(time)$')" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "arctic-bryan", + "metadata": {}, + "outputs": [], + "source": [ + "result = []\n", + "# for nel in results['cg']['nel']:\n", + "results['cg']['nel'][10]\n", + "solver='cg'\n", + "cg = np.load('scalar_field/{}_{}.npy'.format(solver,nel))\n", + "solver='lsqr'\n", + "pyamg=np.load('scalar_field/{}_{}.npy'.format(solver,nel))\n", + "result.append(np.sum(np.abs(cg-pyamg)))\n", + "strati = model.create_and_add_foliation('strati',nelements=nel,solver='pyamg',interpolatortype='FDI')\n", + "strati.interpolator.c = cg\n", + "strati2 = model.create_and_add_foliation('strati',nelements=nel,solver='pyamg',interpolatortype='FDI')\n", + "strati2.interpolator.c = pyamg\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "parliamentary-breeding", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/lgrose/dev/python/LoopStructural/LoopStructural/visualisation/model_visualisation.py:305: FutureWarning: marching_cubes_lewiner is deprecated in favor of marching_cubes. marching_cubes_lewiner will be removed in version 0.19\n", + " verts, faces, normals, values = marching_cubes(\n", + "/home/lgrose/dev/python/LoopStructural/LoopStructural/visualisation/model_visualisation.py:305: FutureWarning: marching_cubes_lewiner is deprecated in favor of marching_cubes. marching_cubes_lewiner will be removed in version 0.19\n", + " verts, faces, normals, values = marching_cubes(\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + " \n", + "
\n", + "
\n", + "

Objects:

\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "slices = [0,60,250,320]\n", + "view = LavaVuModelViewer(model)\n", + "view.add_isosurface(strati,slices=slices,colour='blue')\n", + "view.add_isosurface(strati2,slices=slices)\n", + "view.interactive()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "spare-content", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([4., 2., 2., 2., 3., 2., 2., 1., 0., 2.]),\n", + " array([0.0127047 , 0.45990958, 0.90711446, 1.35431934, 1.80152422,\n", + " 2.2487291 , 2.69593398, 3.14313886, 3.59034374, 4.03754862,\n", + " 4.4847535 ]),\n", + " )" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import time\n", + "from tqdm import tqdm\n", + "\n", + "results= {}\n", + "for solver in ['pyamg','cg','lsqr']:\n", + " results[solver] = {'nx':[],'nel':[],'time':[],'c':[]}\n", + " for nel in tqdm(np.arange(1e3,1e5,5e3)):\n", + " start = time.time()\n", + "# solver = 'pyamg'\n", + " # nelements=1e4\n", + " strati = model.create_and_add_foliation('strati',nelements=nel,solver=solver,interpolatortype='FDI')\n", + " strati.builder.update()\n", + " results[solver]['time'].append(time.time()-start)\n", + " results[solver]['nx'].append(strati.interpolator.nx)\n", + " results[solver]['nel'].append(nel)\n", + " np.save('scalar_field/{}_{}.npy'.format(solver,nel),strati.interpolator.c)\n", + "# results[solver]['c'].append(strati.interpolator.c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "finnish-leeds", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/dev/solver time estimate.ipynb b/dev/solver time estimate.ipynb new file mode 100644 index 000000000..0e884aced --- /dev/null +++ b/dev/solver time estimate.ipynb @@ -0,0 +1,2976 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "id": "noted-overview", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2021-02-03 09:06:23,796 ~ LoopStructural.modelling.core.geological_model ~ WARNING ~ Cannot import Surfe\n" + ] + } + ], + "source": [ + "#import required \n", + "from LoopStructural import GeologicalModel\n", + "from LoopStructural.datasets import load_claudius\n", + "from LoopStructural.visualisation import LavaVuModelViewer\n", + "from scipy.spatial.transform import Rotation as R\n", + "from scipy.ndimage.interpolation import rotate\n", + "import pyamg\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "neural-alignment", + "metadata": {}, + "outputs": [], + "source": [ + "import pyamg\n", + "pyamg.solve?" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "complimentary-conservation", + "metadata": {}, + "outputs": [], + "source": [ + "data, bb = load_claudius() # load data\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "meaningful-chicago", + "metadata": {}, + "outputs": [], + "source": [ + "model = GeologicalModel(bb[0,:],bb[1,:])\n", + "model.set_model_data(data)\n", + "strati = model.create_and_add_foliation('strati',nelements=1e5,solver='pyamg',interpolatortype='FDI')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "three-extent", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 20/20 [06:44<00:00, 20.23s/it]\n", + "100%|██████████| 20/20 [14:22<00:00, 43.15s/it]\n", + "100%|██████████| 20/20 [04:54<00:00, 14.73s/it]\n", + "100%|██████████| 20/20 [15:26<00:00, 46.32s/it] \n", + "100%|██████████| 20/20 [6:17:04<00:00, 1131.25s/it] \n", + "100%|██████████| 20/20 [12:08<00:00, 36.45s/it]\n" + ] + } + ], + "source": [ + "import time\n", + "from tqdm import tqdm\n", + "\n", + "results= {}\n", + "for solver in ['pyamg','chol','cg','chol','lu','lsqr']:\n", + " results[solver] = {'nx':[],'nel':[],'time':[],'c':[]}\n", + " for nel in tqdm(np.arange(1e3,1e5,5e3)):\n", + " start = time.time()\n", + "# solver = 'pyamg'\n", + " # nelements=1e4\n", + " strati = model.create_and_add_foliation('strati',nelements=nel,solver=solver,interpolatortype='FDI')\n", + " strati.builder.update()\n", + " results[solver]['time'].append(time.time()-start)\n", + " results[solver]['nx'].append(strati.interpolator.nx)\n", + " results[solver]['nel'].append(nel)\n", + " np.save('scalar_field/{}_{}.npy'.format(solver,nel),strati.interpolator.c)\n", + "# results[solver]['c'].append(strati.interpolator.c)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "heated-marijuana", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for solver in results.keys():\n", + " plt.scatter(results[solver]['nel'],(results[solver]['nx']),label=solver)\n", + "plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "accomplished-account", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, '$log_e(time)$')" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for solver in results.keys():\n", + " plt.scatter(results[solver]['nel'],np.log(results[solver]['time']),label=solver)\n", + "plt.legend()\n", + "plt.xlabel('Number of elements')\n", + "plt.ylabel(r'$log_e(time)$')" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "brave-classification", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, '$log_e(time)$')" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZkAAAEGCAYAAAC3lehYAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAAAvFElEQVR4nO3de3xU9Z3/8deHJBhEDSi3cFugaxVEEBovLdVaqFAvKLZiba0r6upWa426ayvrVlNrt1rbCu5211pbL22tIrK2FC31B1WLt8pNUJGKiDUQBNHECkGT8Pn9cU5gEkKY4cyZM5m8n49HHjPnO+fyPZnJfPK9m7sjIiIShy5JZ0BERAqXgoyIiMRGQUZERGKjICMiIrFRkBERkdgUJ52BbOrVq5cPGTIk6WyIiHQoS5Ysecfde8dx7oIKMkOGDGHx4sVJZ0NEpEMxszfjOreqy0REJDYKMiIiEhsFGRERiU1Btcm0paGhgerqarZv3550VvJGaWkpAwcOpKSkJOmsiEiBK/ggU11dzYEHHsiQIUMws6Szkzh3Z8uWLVRXVzN06NCksyMiBa7gq8u2b9/OIYccogATMjMOOeQQlexECsWKWXDbSKjqETyumJV0jloo+JIMoADTin4fIgVixSyYewU01AfbdW8F2wCjzk4uXykKviQjIlKwFty4K8A0a6gP0vNEzoKMmf3CzDaZ2Uspabea2atmtsLM/s/MeqS8Nt3M1pjZajOblKt8iojkVJTqrrrqzNITkMuSzD3A51ulPQ6MdPdRwF+B6QBmNgI4BzgiPOZ/zKwod1kVEcmB5uquurcA31XdlW6gKRuYWXoCchZk3P0p4N1WaX9098Zw8zmg+TdzBvCAu3/o7m8Aa4BjcpHPR5atZ9zNCxl67TzG3byQR5atj3zOdevWcfjhh3PuuecyfPhwzjrrLB599FGmTJmyc5/HH3+cM888E4BLL72UiooKjjjiCG644Yad+wwZMoTp06dz1FFHUVFRwdKlS5k0aRIf+9jHuOOOOwDYsWMHl112GYcffjgnnXQSp5xyCrNnz458DyISg6jVXROuh5JuLdNKugXpeSKf2mQuBB4Lnw8A3kp5rTpM242ZXWJmi81s8ebNmyNl4JFl65k+ZyXra+txYH1tPdPnrMxKoFm9ejWXXXYZq1at4qCDDuLll1/m1VdfpTnPd999NxdeeCEA3/ve91i8eDErVqzgySefZMWKFTvPM3jwYJYvX87xxx/PtGnTmD17Ns8999zOYDRnzhzWrVvHK6+8wi9/+UueffbZyHkXkZhEre4adTZMvh3KBgEWPE6+PW8a/SFPgoyZXQc0Ar/O9Fh3v9PdK9y9onfvaJOI3jp/NfUNTS3S6huauHX+6kjnBRg0aBDjxo0D4Ktf/SpPP/005513Hr/61a+ora3l2Wef5eSTTwZg1qxZjB07ljFjxvDyyy/zyiuv7DzP6aefDsCRRx7Jsccey4EHHkjv3r3Zb7/9qK2tZdGiRUydOpUuXbrQr18/PvvZz0bOu4jEJBvVXaPOhqtegqra4DGPAgzkQRdmM5sGnAZMcHcPk9cDg1J2GximxWpDbX1G6Zlo3W3YzLjggguYPHkypaWlTJ06leLiYt544w1++MMf8sILL9CzZ0+mTZvWYkzLfvvtB0CXLl12Pm/ebmxsRCRjK2YF1TN11cGX24Tr8+6LqmBNuL5lF2TIu+quqBItyZjZ54FvAqe7+7aUl34HnGNm+5nZUOBQ4C9x56d/j24ZpWfib3/7286qq/vvv59Pf/rT9O/fn/79+3PTTTdxwQUXAPD+++/TvXt3ysrKePvtt3nsscfaO+1uxo0bx8MPP8yOHTt4++23eeKJJyLnXQpY1IZniaYDVHdFlbOSjJn9BjgR6GVm1cANBL3J9gMeD//Tf87dv+buL5vZLOAVgmq0r7t7U9tnzp5rJh3G9DkrW1SZdSsp4ppJh0U+92GHHcZPfvITLrzwQkaMGMGll14KwLnnnsvmzZsZPnw4AKNHj2bMmDEcfvjhLarY0vXFL36RBQsWMGLECAYNGsTYsWMpKyuLnH8pUO01PBfQF11eG3V2Qf+ubVcNVcdXUVHhrRctW7Vq1c4v8HQ8smw9t85fzYbaevr36MY1kw5jypg2+xykbd26dZx22mm89NJLu712+eWXM2bMGC666KJI10j1wQcfcMABB7BlyxaOOeYYnn76afr169din0x/L1KgqnoAbX0HWFDHL52CmS1x94o4zp14m0y+mTJmQOSgkq5PfOITdO/enR/96EdZPe9pp51GbW0tH330Ed/+9rd3CzAiO5UNDKvK2kgXyQIFmRwYMmRIm6WYJUuWxHI9tcNI2jpBw7MkKy+6MItIQjpBw7MkSyUZkc6uwBueJVkqyYiISGwUZEREJDYKMglpnncsXevWrWPkyJEx5khEJPsUZEREJDYKMq3FtF72fffdx6hRoxg9ejTnnXceAE899RSf+tSnGDZs2M5SjbtzzTXXMHLkSI488kgefPDBrFxfRCQJ6l2WKqb1sl9++WVuuukmnnnmGXr16sW7777L1VdfTU1NDYsWLeLVV1/l9NNP56yzzmLOnDksX76cF198kXfeeYejjz6aE044IQs3JyKSeyrJpIppveyFCxcydepUevXqBcDBBx8MwJQpU+jSpQsjRozg7bffBmDRokV8+ctfpqioiL59+/KZz3yGF154IdL1RUSSoiCTKsfrZadO1V9Ic8iJiDRTkEkV03rZ48eP56GHHmLLli0AvPvuu3vc9/jjj+fBBx+kqamJzZs389RTT3HMMTlZeVpEJOvUJpMqpnmcjjjiCK677jo+85nPUFRUxJgxY/a475lnnsmzzz7L6NGjMTN+8IMf0K9fP9atWxcpDyIiSdBU/611klUCNdW/iDTTVP+5pHmcRESyRm0yIiISGwUZERGJjYKMiIjERkFGRERioyAjIiKxUZAREZHYKMiIiEhsFGRambd2HhNnT2TUvaOYOHsi89bOy8p5W0/1//rrr3Pcccdx5JFH8h//8R8ccMABWbmOiEg+yVmQMbNfmNkmM3spJe1gM3vczF4LH3uG6WZmt5vZGjNbYWZjc5HHeWvnUfVMFTVba3Ccmq01VD1TFTnQNE/1v3DhQl588UVmzpxJZWUllZWVrFy5koEDo82NJiKSr3JZkrkH+HyrtGuBBe5+KLAg3AY4GTg0/LkE+N9cZHDm0plsb9reIm1703ZmLp0Z6bxtTfX/7LPPMnXqVAC+8pWvRDq/iEi+ylmQcfengNbTD58B3Bs+vxeYkpJ+nweeA3qYWXncedy4dWNG6SIi0r6k22T6untN+Hwj0Dd8PgB4K2W/6jBtN2Z2iZktNrPFmzdvjpSZft37ZZSerram+j/uuON4+OGHAXjggQcinV9EJF8lHWR28mA66IynhHb3O929wt0revfuHSkPlWMrKS0qbZFWWlRK5djKSOdNnep/9OjRXH311cyYMYMf//jHjBo1ijVr1lBWVhbpGiLSMdXNnctr4yewavgIXhs/gbq5c3N6fNySnoX5bTMrd/easDpsU5i+HhiUst/AMC1Wpw47FQjaZjZu3Ui/7v2oHFu5Mz2K888/n/PPP3/n9rZt23juuecwMx544AFWr14d+Roi0rHUzZ1Lzbevx7cHbcGNGzZQ8+1g/aqyyZNjPz4Xkg4yvwPOB24OH3+bkn65mT0AHAvUpVSrxerUYadmJajszZIlS7j88stxd3r06MEvfvGL2K8pIvll020zdgaIZr59O5tum5FWkIh6fC7kLMiY2W+AE4FeZlYN3EAQXGaZ2UXAm0DzQi6PAqcAa4BtwAW5ymeuHH/88bz44otJZ0NEEtRY0/b/zntKz/bxuZCzIOPuX97DSxPa2NeBr8ebIxGRZBWXl9O4YUOb6bk4PhfypuFfRKSz6XPVlVhpy85GVlpKn6uuzMnxuZB0m4yISMe2YhYsuBHqqqFsIEy4Pu0l3JvbTTbdNoPGmhqKy8vpc9WVabenRD0+FxRkRET21YpZMPcKaKgPtuveCrYho0ATJShEPT5uqi7LAU1+KVKgFty4K8A0a6gP0gVQkOkwGhsbk86CiLRWV51ZeiekINNKnKNna2pqOOGEEzjqqKMYOXIkf/7znwG4++67+fjHP84xxxzDxRdfzOWXXw7AtGnT+NrXvsaxxx7LN7/5zazlQ0SypGwPM6jvKb0TUptMirhHz95///1MmjSJ6667jqamJrZt20ZNTQ033HADS5YsoaysjM9+9rOMGTNm5zHV1dU888wzFBUVRb6+iLQhQsM9E65v2SYDUNItSBdAJZkW2hs9mw1HH300d999N1VVVaxcuZIDDzyQ559/nhNPPJHevXvTtWtXvvSlL7U4ZurUqQowInFpbrivewvwXQ33K2ald/yos2Hy7VA2CLDgcfLt6QepTkAlmRRxj5494YQTeOqpp5g3bx7Tpk3j6quv5qCDDmr3mO7du2fl2iLShvYa7tMNFKPOVlBph0oyKfY0SjZbo2fffPNN+vbty8UXX8w///M/s3TpUo499liefPJJtmzZQkNDAw899FBWriUiaVDDfewUZFLEPXr2iSeeYPTo0YwZM4YHH3yQyspKysvLqaqq4pOf/CTjxo1j+PDhWbmWiKRBDfexs2CasMJQUVHhixcvbpG2atWqjL646+bOTXT07D333MPixYv57//+71ivk+nvRaQgtR5MCUHDfSdrVzGzJe5eEce51SbTSr6PnhWRLGoOJPvau0z2SkEmz0ybNo1p06YlnQ2RzkMN97HqFG0yhVQlmA36fYhIrhR8kCktLWXLli36Yg25O1u2bKG0VQcHEZE4FHx12cCBA6murmbz5s1JZyVvlJaWMnCges+ISPwKPsiUlJQwdOjQpLMhItIpFXx1mYiIJEdBRkREYqMgIyIisVGQERGR2CjIiIhIbPIiyJjZVWb2spm9ZGa/MbNSMxtqZs+b2Roze9DMuiadTxERyUziQcbMBgBXABXuPhIoAs4BbgFuc/d/BN4DLkoulyIibYtzyfZCkHiQCRUD3cysGNgfqAHGA7PD1+8FpiSTNRGRtjUv2d64YQO471yyXYFml8SDjLuvB34I/I0guNQBS4Bad28Md6sGBrR1vJldYmaLzWyxRvWLSC7FvWR7IUg8yJhZT+AMYCjQH+gOfD7d4939TnevcPeK3r17x5RLEZHdxb1keyFIPMgAnwPecPfN7t4AzAHGAT3C6jOAgcD6pDIoItKWuJdsLwT5EGT+BhxnZvubmQETgFeAPwFnhfucD/w2ofyJiLQp7iXbC0HiE2S6+/NmNhtYCjQCy4A7gXnAA2Z2U5j28+RyKSKyu+ZVdJNcsj3fWSGts1JRUeGLFy9OOhsikksrZmn55IjMbIm7V8Rx7sRLMiIi+2zFLJh7BTTUB9t1bwXboECTJ/KhTUZEZN8suHFXgGnWUB+kS17IOMiYWXczK4ojMyIiGamrzixdcm6vQcbMupjZV8xsnpltAl4FaszsFTO71cz+Mf5sioi0oWwPy4jvKV1yLp2SzJ+AjwHTgX7uPsjd+wCfBp4DbjGzr8aYRxGRtk24Hkq6tUwr6RakS15Ip+H/c+EgyRbc/V3gYeBhMyvJes5ERPamuXFfvcvy1l6DTHOAMbNDCUoz9e7+9bb2ERHJuVFnRwoqdXPnapxLjDJp+P8l8BBwPICZjTSz+2LJlYhIDmgW5fhlEmS6uPtjQBOAu78EjIwlVyIiOaBZlOOXSZDZYGZDAQcI5xnr1v4hIiL5S7Moxy+TIHMl8DOgn5ldADwAvBRHpkREckGzKMcv7SDj7usI1nmpBIYBTwLnxZMtEekwVsyC20ZCVY/gccWspHOUNs2iHL9M5y4zd3+IoAOAiHR2HXzuMM2iHL+0Z2E2s58BpxFMx78BWAGscPf/ii97mdEszCI5dtvIILC0VjYIrkqzNl2zKCcuX2ZhPgEY6O5NZjYAGA2MiiNTItJBRJ07rIOXhGTvMmn4fx44BMDd17v7o+5+czzZEpEOIercYZpFueBlEmR+CjxpZv9mZsebWVlcmRKRDiLq3GFZmEW5bu5cXhs/gVXDR/Da+AkaSJlnMgkyvwLuI6hiuwx4xsxejyVXItIxjDobJt8etMFgwePk29Ov6opYEtKI/fyXScP/n939+FZp+7n7h7HkbB+o4V+kg2ndJgNBSSjNQPXa+AlBgGmluH9/Dl24IJs5LWhxNvxnUpJZbmaVqQn5FGBEpAOKWBLSiP38l0nvsr7A58zsW8BS4EVgeThuRkRk30SYRbm4vLztkoxG7OeNTEb8n+3uw4GhwPXAX4Fj48qYiMjeaMR+/ttrScbMqty9yszGEQy+/DtBSWZp7LkTEWmHRuznv3Sqy+aHj5XAyHAVzFfYNeJf1WUikpiyyZMVVPLYXqvL3P3Z8Ok33X0EwRoy3wHWAMdkIxNm1sPMZpvZq2a2ysw+aWYHm9njZvZa+NgzG9cSEZHcyaR32RwIepS5+1J3vxd4OEv5mAn8wd0PJ5iuZhVwLbDA3Q8FFoTbIiLSgew1yJjZ2WZ2M3CgmQ03s9Rj7oyagXDmgBOAnwO4+0fuXgucAdwb7nYvMCXqtUREJLfSKck8TdAG0xP4MbDGzJaa2e+B+naPTM9QYDNwt5ktM7O7zKw70Nfdmzu7byToQr0bM7vEzBab2eLNmzdnITsiIpIte234d/f1wH1m9rq7Pw1gZocAQ4BXs5SHscA33P15M5tJq6oxd3cza3NqAne/k7BEVVFRkd70BSIikhPpVJcZQHOACZ9vcfcl7r41dZ99VA1Uu/vz4fZsgqDztpmVh+cvBzZFuIaIiCQgneqyP5nZN8xscGqimXU1s/Fmdi9w/r5mwN03Am+Z2WFh0gSC6rnfpZz3fOC3+3oNERFJRjrjZD4PXAj8xsyGArVAN4IA9Udghrsvi5iPbwC/NrOuwFrggvD8s8zsIuBNQCsYiYh0MOm0yWwH/gf4n3AgZi+gPuwBlhXuvhxoawbQCdm6hoiI5F4m42Rw94awx9d3zOxuADObGEvORESkw8soyKTYAbwRPh+fpbyISCeklS0LWyZT/afaBpSF1WeD97aziEhbmle29O3bAXaubAloPrICsa8lmRuA14GfAPdnLzsi0plsum3GzgDTzLdvZ9NtM5LJkGTdPpVk3L2RoDOAiMg+08qWhS/tIGNmrwErCVfEBF5093XxZEtEOgOtbFn4Mqku+ynBHGJbgJOBl8xspZndGLbNiIhkRCtbFr5Mqsu+6u5HNW+Y2R0EgzTfJ5g48xvZzZqIdAR1c+fu88qUWtmy8GUSZOrMbJS7r4BgAKWZfcbdR5uZlmIW6YSy0TtMK1sWtkyCzNeAX5nZcoI2mcMIujIDdM1utkSkI2ivd5gCh0AGbTLuvopgueU/AH0Ill8+LVz75YF4sici+Uy9w2RvMulddjBwFUGAeQW4z93fC1++KYa8iUieU+8w2ZtMepc9APwdmAvsDywys2NiyZWIdAjqHSZ7k0mbTG93/0H4/Pdm9iDBaP/jsp8tEekI1DtM9iaTIPOumR3p7isB3H2tme0fU75EpINQ7zBpTyZB5jLgYTP7M8HI/yMI5i8TERFp016DjJn9ElhGMJ3MeOBEYHiY9q9xZk5ERDq2dEoydwOjgfPCxzKC3mVdgcnAQ7HlTkREOrR0ll9eCCxs3jazYoKSzGiCcTMKMiIi0qaM15Nx90Z3X+nuv3L3a+LIlIjkjlamlDjt68qYIlIAtDKlxG1fV8YUkQKglSklbgoyIp2Y5h6TuOVNkDGzIjNbZma/D7eHmtnzZrbGzB40M830LNKWFbPgtpFQ1SN4XDEr7UP3NMeY5h6TbMmbIANUAqtStm8BbnP3fwTeAy5KJFci+WzFLJh7BdS9BXjwOPeKtAON5h6TuOVFkDGzgcCpwF3hthEM/Jwd7nIvMCWRzInkswU3QkN9y7SG+iA9DWWTJ7P+oqt4p3tPdgDvdO/J+ouuUqO/ZE2+9C6bAXwTODDcPgSodffGcLsaGNDWgWZ2CXAJwODBg+PNpUi+qavOLL2VR5atZ/qmPtSfdN3OtG6bivj+svVMGdPmn5xIRhIvyZjZacAmd1+yL8e7+53uXuHuFb17985y7kTyXNnAzNJbuXX+auobmlqk1Tc0cev81VFzJgLkQZABxgGnm9k6gjVrxgMzgR7h7AIAA4H1yWRPJI9NuB5KurVMK+kWpKdhQ219RukimUo8yLj7dHcf6O5DgHOAhe5+LvAn4Kxwt/OB3yaURZH8NepsmHw7lA0CLHicfHuQnob+PbpllC7ZN2/tPCbOnsioe0cxcfZE5q2dl3SWsirxINOObwFXm9kagjaanyecH5G89EjTOMZ9eDtDt/+acR/eziNN49I+9ppJh9GtpKhFWreSIq6ZdFi2syltmLd2HlXPVFGztQbHqdlaQ9UzVQUVaMzdk85D1lRUVPjixYuTzoZIzjyybD3T56xs0a7SraSI73/hyLQb7h9Ztp5b569mQ209/Xt045pJh6nRP0cmzp5IzdbdB76Wdy/nj2f9Ma1zzFs7j5lLZ7Jx60b6de9H5dhKTh12akb5MLMl7l6R0UFpypfeZSKyD26dv5pj1/6Faa88Ru/6WjZ368E9I07m1vld0w4UU8YMUFBJyMatGzNKb625JLS9KZgaqLkkBGQcaOKSz9VlIrIXH1+5iMrls+lbX0sXoG99LZXLZ/PxlYuSzpqkoV/3fhmltzZz6cydAabZ9qbtzFw6M3LeskVBRqQDu/DVP1Da1NAirbSpgQtf/UNCOZJMVI6tpLSo5YwLpUWlVI6tTOv4qCWhXFB1mUjCorSJHLK1tu30bW2nS35prtLa1zaVft37tdmmk25JKBcUZEQS1Lrhfn1tPdPnrARIK9CU9C+nccOG3dM1wWWHceqwU/e5/aRybGWLNhnIrCSUC6ouE0nQrfNXc1LTkyzqegVr9/sKi7pewUlNT6Y94l4TXHZupw47lapPVVHevRzDKO9eTtWnqvKm0R9UkhFJVMX7j/P9krvY3z4CYKC9w80ldzH9fQgmv2hf80SWm26bQWNNDcXl5fS56kpNcJlD2ehCHEWUklAuaJyMSERR2lQ2Vv0j3dZ9wKYVB9K4rYji/ZvoM+rv1A85gH5Va2LOuUTVugsxBNVV+Vaa2Js4x8moukwkguY2lfW19Ti72lQeWZbeVHul6z6g5oUyGrcVA0bjtmJqXiijdN0HseZbdokyrUtH6EKcNAUZkQiizmK8+aWeeFPLP0Nv6sLml3pmLY+yZ1GndekIXYiTpiAjEkHUWYwbt2aWLtkVtSQSdTBlZ6AgIxJB/x7dOL3Loha9w07vsijtWYyLy/tnlC7ZFbUkEnUwZWegICOd3iPL1jPu5oUMvXYe425emHZ7CsCMEa9xS8ldDOzyDl0MBnZ5h1tK7mLGiNfSOl5dkJMVtSTSEboQJ01dmKVTizoY8ujX/wvC7sfNutlHQTr/stfj1QU5WdkYzJjvXYiTpiAjnVp7DfdpdUOuq84svQ1lkycrqEQQZZxK1GldZO8UZKRTi7z8cNlAqHur7XSJXTamuldJJF5qk5FOLfLywxOuh5JW+5Z0C9Ildhqnkv9UkpEOL8qI+2smHcai//sfruQB+ts7bPBezOAcPj3psvQuPups6v78IpvunkPjB07xAUafC75A2aizI9yRpEvjVPKfgox0aFEb7qcUPc0J1fexZXkpq7eVU7x/E/9+1H0cXDQa2HugqJs7l5qfPYpvBzAaP4Canz0Kg49TO0sOdISp7js7VZdJhxZ1xH3dHVVsen7/FtO6bHp+f+ruqErr+E23zcC3t6yu8e3b2XTbjLSOl2g0TiVaF/xcUElGOrSoDfebnmvAm1r+GXhTFzY910BZGsc31uz+X3R76bK7zt47LEp1b9SSfC4oyEiH1r9HN9a3EVDSbbgPSjDpp7dWXN72omHFnWjRsChBorP3DosaJCJ3wc8BVZdJh3bNpMPoVlLUIq1bSRHXTDosreOLe7VdXtlTemudfcR+1AkmC6F3WJTqqqjVvZG74OeAgox0aFPGDOD7XziSAT26YcCAHt34/heOTPu/uD7fug7rWtIizbqW0Odb16V1fNnkyZR/90aK+/cHM4r796f8uzd2mkb/qEEiH3qHRQkSUZd6iBokInfBz4HEq8vMbBBwH9AXcOBOd59pZgcDDwJDgHXA2e7+XlL5lPhEqZOGINDsa9VANqZ16cwj9qMGiaR7hyVdXRW1uveaSYe1yD9kVpLPhXwoyTQC/+ruI4DjgK+b2QjgWmCBux8KLAi3pcBE/U8wG8omT+bQhQsYvuoVDl24oNMGjH1xUEnvjNJby0bvsI5cXRW1ujdqST4XEi/JuHsNUBM+/7uZrQIGAGcAJ4a73Qs8AXwrgSxKjLLScLliFiy4MZgvrGxgMNpegyFz4sNNk/CyB7AuDTvTfEcJH26alNbxUXuHRS2JZKO6KkpJpDmPSZXkcyHxIJPKzIYAY4Dngb5hAALYSFCd1tYxlwCXAAwePDgHuZRsitxwuWIWzL0CGsL9694KtkGBJgfe2XgERdu+wH6952MltXhDDz7cPImt7x+R9jka6o5i65pr+XttPQf26EbDx9Kv6imE6qp8DxJR5U2QMbMDgIeBK939fTPb+Zq7u5l5W8e5+53AnQAVFRVt7iP5K+ofOQtu3BVgmjXUB+kKMrEL3r8xNL4/pkX6gDTfv6RLIlGDRDZKIoUuL4KMmZUQBJhfu/ucMPltMyt39xozKwc2JZdDaU/UucMi/SeYhan2O7so41yivn9Jl0Q6Q3VV0hIPMhYUWX4OrHL3H6e89DvgfODm8PG3CWRP9iLy3GFR/8jLBlL34jtsWnEgjduKKN6/iT6j/k7Z6F77dkOdTNTBkFHfv6RLIqAgEbfEgwwwDjgPWGlmy8O0fycILrPM7CLgTdKZrVByLhsN91H+yOu6nkHNCw/jTUH1auO2Ympe6AFHn5HWtDCFIEpJpL1xLumeI8r7lw8lEYlX4kHG3RcBtoeXJ+QyL5K5bIw4rps7d5/HqWx6+LmdAaaZNxmbHn6Osq+nnYUOK2pJJOnBkCqJFL58GCcjCYo6g2vUEcd1c+dS8+3rg/m/3GncsIGab19P3dy5aR3f2SeojDrifk+DHnM1GLIjjPOQaBRkOrFsDISMOpgs6lT5e5qIsrNMUBm1JJIPU+VPGTOAp68dzxs3n8rT145XgCkwCjKdWNTRzhD9P9GoJZFCmKBy3tp5TJw9kVH3jmLi7IlpTy4J0Usipw47lapPVVHevRzDKO9eTtWnqjrsrMaSfxJvk5HkZGsG1yh14lGnys/G3GNJitqmUjm2ssXxkHlJpCNPlS/5T0GmE4s8EDIL+lx1JTXXXYd/tGtaEutaklFJpCNPUBm1d1chLNolhU1BphPLhxlcy/6hHo5+j03LSneNcxnzQZDeQUTpQpyN3l0qiUg+U5Dp4KKMts+LMQYLbqRs0PuUDXp/t/SOMC1M1OqupKe6F4mbgkwHlo31vRMfY9DBp4WJWt2VjTYVkXym3mUdWDZ6h2VD3dy5vDZ+AquGj+C18RPSHuMCBFPzZ5Iegyi9u6JWd6l3lxQ6lWQ6sHxY37t5MGXzWJfmwZRAeo3xE65vOVU/QEm3ID0H8qG6S20qUshUkunA8mF976iDKRl1Nky+HcoGARY8Tr49o/aYKCWRqCPm82Ewo0g+U0kmYYlOk58FjTW7j3FpL71No87e50b+pOfuUhdikfYpyCQo8WnyiTY5JUBxd2j8oO30dCU5i7Cqu0TipSCToMSnyY/angL0GfkeNS+U4U27al6taAd9RtaldXzSJRH17hKJl9pkEpR0w33k9hSgbHQvyo+uo3j/RsAp3r+R8qPr0l40LOlZhNW7SyReKskkKBvTukSp7spKe8qE6ynbdgVlQ1JWx86gd1g+lERU3SUSH5VkEhR1mvyoa7Hsqd0kk/YURp3NvHEXM3HwIEYNGcTEwYOYN+7itBvyVRIRKWwqyUQUdVqXAxctoOs9d3Dw1vd4t3tPPpr2NSakeXx71V3plGb6jHyP6hd60CVlZckdRU6fkbVpXR/CNpXqP7C9KDhHTRFUVf8B1h6nWYRFRCWZKKIu+lU3dy4Dfn4bvba+Rxeg19b3GPDz23K2KuSio3vx05ONzQfBDmDzQfDTk41FR6fXngLR21RUEhEpbCrJRBC1d1jUkkjUtVhm9uxBzQF1/OnIlumvlpSR7le8ZhEWkfYoyESwobaeE99awrRXHqN3fS2bu/XgnhEn8ySfSOv4qCWR9ZMG0uOXG9ivcVfah8Xw9qSBHJrG8Rsb3s8ovS2aRVhE2qPqsgjO3LKSyuWz6VtfSxegb30tlctnc+aWlWkdH3V9+v/svYQ7TmlZ3XXHKcZ/9l6S1vFRG91B06qISPs6fUlmwX/dt3vD+zf+Ka1jp616jJKmhhZppU0NTFv1GHDtXo+PXBLpAjVHFPH0ES3TzT2No7PX6A6aVkVE2pb3QcbMPg/MBIqAu9z95myde8F/3UevO26ha9MOIGh4/+iOW1gAaQWaki2bMkpv7T97L2HYKcZXnnAOeR+2HAT3n2is7b2EE9M4vt+OoDdXW+npyFaAUJuKiOxJXgcZMysCfgKcBFQDL5jZ79z9lWycv/u9P9oZYJp1bdpB93t/BGkEmYYDoOTvbaenI3JJZNiZVL3xf2zvsqsLcukOp3LYmellAAUIEYlXvrfJHAOscfe17v4R8ABwRrZOftAHH2WU3tpvjoftrcL09uIgPR17KnGkXRI58btUDT2T8ibH3ClvcqqGnsmpJ343vROIiMQsr0sywADgrZTtauDY1B3M7BLgEoDBgwdndPJ3DoLebXSkeueg9I6fN6qI94p37Fbd9cyILnw/jeOzUhI58bsKKiKSt/I9yOyVu98J3AlQUVGRXj1T6NHjjS/Nd0pTGt63FwfpJ6RxfL+uPXj6iLrdqrvKS8rSun5zcJi59v/Y2CUowVQOU0lERApHvgeZ9cCglO2BYVpWHD/5i9xtD3PWU7tKIrNPMCad9sW0jq88bjpVi77Ndt/Vw6zUSqg8bnraeVBJREQKWb4HmReAQ81sKEFwOQf4SrZO3vzlftOIfStJqPuuiEj7zNPsyZQUMzsFmEHQhfkX7v69Pe1bUVHhixcvzlXWREQKgpktcfeKOM6d7yUZ3P1R4NGk8yEiIpnL9y7MIiLSgSnIiIhIbBRkREQkNgoyIiISm7zvXZYJM9sMvJnBIb2Ad2LKTkeg+9f9d+b7B/0Omu//H9y9dxwXKKggkykzWxxXt72OQPev++/M9w/6HeTi/lVdJiIisVGQERGR2HT2IHNn0hlImO6/c+vs9w/6HcR+/526TUZEROLV2UsyIiISIwUZERGJTacNMmb2eTNbbWZrzOzapPOzr8xskJn9ycxeMbOXzawyTD/YzB43s9fCx55hupnZ7eF9rzCzsSnnOj/c/zUzOz8l/RNmtjI85nYzs91zkiwzKzKzZWb2+3B7qJk9H+b5QTPrGqbvF26vCV8fknKO6WH6ajOblJKe958VM+thZrPN7FUzW2Vmn+xMnwEzuyr8/L9kZr8xs9JC/gyY2S/MbJOZvZSSFvv7vadrtMvdO90PwbIBrwPDgK7Ai8CIpPO1j/dSDowNnx8I/BUYAfwAuDZMvxa4JXx+CvAYYMBxwPNh+sHA2vCxZ/i8Z/jaX8J9LTz25KTvu43fw9XA/cDvw+1ZwDnh8zuAS8PnlwF3hM/PAR4Mn48IPwf7AUPDz0dRR/msAPcC/xw+7wr06CyfAYJl2t8AuqW899MK+TMAnACMBV5KSYv9/d7TNdrNa9IfkITeoE8C81O2pwPTk85Xlu7tt8BJwGqgPEwrB1aHz38KfDll/9Xh618GfpqS/tMwrRx4NSW9xX758EOwYuoCYDzw+/AP4x2guPX7DcwHPhk+Lw73s9afgeb9OsJnBSgLv2StVXqn+AwQBJm3wi/L4vAzMKnQPwPAEFoGmdjf7z1do72fzlpd1vyhbFYdpnVoYbF/DPA80Nfda8KXNgJ9w+d7uvf20qvbSM8nM4BvAjvC7UOAWndvDLdT87zzPsPX68L9M/295JOhwGbg7rDK8C4z604n+Qy4+3rgh8DfgBqC93QJneszALl5v/d0jT3qrEGm4JjZAcDDwJXu/n7qax7821GQfdXN7DRgk7svSTovCSomqDr5X3cfA2wlqMrYqcA/Az2BMwiCbX+gO/D5RDOVsFy83+leo7MGmfXAoJTtgWFah2RmJQQB5tfuPidMftvMysPXy4FNYfqe7r299IFtpOeLccDpZrYOeICgymwm0MPMmld+Tc3zzvsMXy8DtpD57yWfVAPV7v58uD2bIOh0ls/A54A33H2zuzcAcwg+F53pMwC5eb/3dI096qxB5gXg0LD3SVeCxr/fJZynfRL2+vg5sMrdf5zy0u+A5t4i5xO01TSn/1PY4+Q4oC4s/s4HJppZz/A/w4kE9dA1wPtmdlx4rX9KOVfi3H26uw909yEE7+NCdz8X+BNwVrhb6/tv/r2cFe7vYfo5Yc+jocChBI2fef9ZcfeNwFtmdliYNAF4hU7yGSCoJjvOzPYP89d8/53mMxDKxfu9p2vsWdKNVwk2mp1C0BPrdeC6pPMT4T4+TVBkXQEsD39OIahjXgC8Bvw/4OBwfwN+Et73SqAi5VwXAmvCnwtS0iuAl8Jj/ptWDcz58gOcyK7eZcMIviDWAA8B+4XppeH2mvD1YSnHXxfe42pSek91hM8KcBSwOPwcPELQW6jTfAaA7wCvhnn8JUEPsYL9DAC/IWh/aiAoyV6Ui/d7T9do70fTyoiISGw6a3WZiIjkgIKMiIjERkFGRERioyAjIiKxUZAREZHYKMhIXjMzN7MfpWz/m5lVZenc95jZWXvfM/J1plowM/KfMjjmgzjztJdr/3tS15bCoyAj+e5D4Atm1ivpjKRKGUmejouAi939s3HlJ8sUZCRrFGQk3zUSrEN+VesXWpdEmv/7N7MTzexJM/utma01s5vN7Fwz+0u4RsbHUk7zOTNbbGZ/DedBa16b5lYzeyFcf+NfUs77ZzP7HcGI8tb5+XJ4/pfM7JYw7XqCAbM/N7Nb2zjmmpTrfKetX0Bb+5jZEAvWjrknzPuvzexzZva0BWt9HBPu192CtUf+YsHkmWeE6dPMbI6Z/SHc/wdh+s1ANzNbHp6zu5nNM7MXw/v60l7fMZFUSY9c1Y9+2vsBPgAOAtYRzDH1b0BV+No9wFmp+4aPJwK1BFOR70cw79J3wtcqgRkpx/+B4J+tQwlGTpcClwD/Ee6zH8FI+qHhebcCQ9vIZ3+C6U16E0xYuRCYEr72BCmjrFOOmUgQQC3Mw++BE1rdS5v7EEzz3ggcGaYvAX4R7ncG8Eh4/H8CXw2f9yAYtd6dYL2VteHvtBR4ExiUeu3w+ReBn6VslyX9mdBPx/pRSUbyngezSt8HXJHBYS+4e427f0gwNcYfw/SVBF/QzWa5+w53f43gS/dwgi/2fzKz5QTLJhxCEIQA/uLub7RxvaOBJzyYpLER+DVBMGjPxPBnGbA0vPahGezzhruvdPcdwMvAAnf3Vvc4Ebg2vJcnCALK4PC1Be5e5+7bCUpm/9BGHlcCJ5nZLWZ2vLvX7eWeRFrIpF5ZJEkzCL5k705JaySs8jWzLgSrFjb7MOX5jpTtHbT83LeeV8kJSgPfcPf5qS+Y2YkEJZlsMeD77v7TTPexYO2gdO7RgC+6++pWxx/b6vgm2vg+cPe/WrBc7ynATWa2wN1v3NuNiTRTSUY6BHd/l2A53YtSktcBnwifnw6U7MOpp5pZl7CdZhjBxIjzgUstWEIBM/u4BYuAtecvwGfMrJeZFRGsJvjkXo6ZD1xowVpAmNkAM+uzD/vs7RrfCGfTxczGpHFMQ8q99we2ufuvgFsJlhAQSZtKMtKR/Ai4PGX7Z8BvzexFgraVfSll/I0gQBwEfM3dt5vZXQTVTUvDL+fNwJT2TuLuNWZ2LcH08gbMc/d2p0F39z+a2XDg2TAGfAB8lZQ1OtrZpynN+/suQSlwRVjaewM4bS/H3Bnuv5SgmvJWM9tBMOPvpWleVwRAszCLiEh8VF0mIiKxUZAREZHYKMiIiEhsFGRERCQ2CjIiIhIbBRkREYmNgoyIiMTm/wNIcFFnqWmlCQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for solver in results.keys():\n", + " if solver == 'lu':\n", + " continue\n", + " plt.scatter(results[solver]['nel'],(results[solver]['time']),label=solver)\n", + "plt.legend()\n", + "plt.xlabel('Number of elements')\n", + "plt.ylabel(r'$log_e(time)$')" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "arctic-bryan", + "metadata": {}, + "outputs": [], + "source": [ + "result = []\n", + "# for nel in results['cg']['nel']:\n", + "results['cg']['nel'][10]\n", + "solver='cg'\n", + "cg = np.load('scalar_field/{}_{}.npy'.format(solver,nel))\n", + "solver='lsqr'\n", + "pyamg=np.load('scalar_field/{}_{}.npy'.format(solver,nel))\n", + "result.append(np.sum(np.abs(cg-pyamg)))\n", + "strati = model.create_and_add_foliation('strati',nelements=nel,solver='pyamg',interpolatortype='FDI')\n", + "strati.interpolator.c = cg\n", + "strati2 = model.create_and_add_foliation('strati',nelements=nel,solver='pyamg',interpolatortype='FDI')\n", + "strati2.interpolator.c = pyamg\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "forbidden-array", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/lgrose/dev/python/LoopStructural/LoopStructural/visualisation/model_visualisation.py:305: FutureWarning: marching_cubes_lewiner is deprecated in favor of marching_cubes. marching_cubes_lewiner will be removed in version 0.19\n", + " verts, faces, normals, values = marching_cubes(\n", + "/home/lgrose/dev/python/LoopStructural/LoopStructural/visualisation/model_visualisation.py:305: FutureWarning: marching_cubes_lewiner is deprecated in favor of marching_cubes. marching_cubes_lewiner will be removed in version 0.19\n", + " verts, faces, normals, values = marching_cubes(\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + " \n", + "
\n", + "
\n", + "

Objects:

\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "slices = [0,60,250,320]\n", + "view = LavaVuModelViewer(model)\n", + "view.add_isosurface(strati,slices=slices,colour='blue')\n", + "view.add_isosurface(strati2,slices=slices)\n", + "view.interactive()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "patent-villa", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([4., 2., 2., 2., 3., 2., 2., 1., 0., 2.]),\n", + " array([0.0127047 , 0.45990958, 0.90711446, 1.35431934, 1.80152422,\n", + " 2.2487291 , 2.69593398, 3.14313886, 3.59034374, 4.03754862,\n", + " 4.4847535 ]),\n", + " )" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import time\n", + "from tqdm import tqdm\n", + "\n", + "results= {}\n", + "for solver in ['pyamg','cg','lsqr']:\n", + " results[solver] = {'nx':[],'nel':[],'time':[],'c':[]}\n", + " for nel in tqdm(np.arange(1e3,1e5,5e3)):\n", + " start = time.time()\n", + "# solver = 'pyamg'\n", + " # nelements=1e4\n", + " strati = model.create_and_add_foliation('strati',nelements=nel,solver=solver,interpolatortype='FDI')\n", + " strati.builder.update()\n", + " results[solver]['time'].append(time.time()-start)\n", + " results[solver]['nx'].append(strati.interpolator.nx)\n", + " results[solver]['nel'].append(nel)\n", + " np.save('scalar_field/{}_{}.npy'.format(solver,nel),strati.interpolator.c)\n", + "# results[solver]['c'].append(strati.interpolator.c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "convinced-surrey", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/dev/solver_diagnostic.py b/dev/solver_diagnostic.py new file mode 100644 index 000000000..16c0611ff --- /dev/null +++ b/dev/solver_diagnostic.py @@ -0,0 +1,67 @@ +####################################################################### +# Function definition automatically generated by solver_diagnostics.py +# +# Use the function defined here to generate and run the best +# smoothed aggregation method found by solver_diagnostics(...). +# The only argument taken is a CSR/BSR matrix. +# +# To run: >>> # User must load/generate CSR/BSR matrix A +# >>> from solver_diagnostic import solver_diagnostic +# >>> solver_diagnostic(A) +####################################################################### + +from pyamg import smoothed_aggregation_solver +from pyamg.util.linalg import norm +from numpy import ones, array, arange, zeros, abs, random +from scipy import rand, ravel, log10, kron, eye +from scipy.io import loadmat +from scipy.sparse import isspmatrix_bsr, isspmatrix_csr +import pylab + +def solver_diagnostic(A): + ## + # Generate B + test + + ## + # Random initial guess, zero right-hand side + random.seed(0) + b = zeros((A.shape[0],1)) + x0 = rand(A.shape[0],1) + + ## + # Create solver + ml = smoothed_aggregation_solver(A, B=B, BH=BH, + strength=('symmetric', {'theta': 0.0}), + smooth="jacobi", + improve_candidates=[('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None], + aggregate="standard", + presmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), + postsmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), + max_levels=15, + max_coarse=300, + coarse_solver="pinv") + + ## + # Solve system + res = [] + x = ml.solve(b, x0=x0, tol=1e-08, residuals=res, accel="cg", maxiter=300, cycle="V") + res_rate = (res[-1]/res[0])**(1.0/(len(res)-1.)) + normr0 = norm(ravel(b) - ravel(A*x0)) + print(" ") + print(ml) + print("System size: " + str(A.shape)) + print("Avg. Resid Reduction: %1.2f" % res_rate) + print("Iterations: %d" % len(res)) + print("Operator Complexity: %1.2f" % ml.operator_complexity()) + print("Work per DOA: %1.2f" % (ml.cycle_complexity()/abs(log10(res_rate)))) + print("Relative residual norm: %1.2e" % (norm(ravel(b) - ravel(A*x))/normr0)) + + ## + # Plot residual history + pylab.semilogy(array(res)/normr0) + pylab.title('Residual Histories') + pylab.xlabel('Iteration') + pylab.ylabel('Relative Residual Norm') + pylab.show() + diff --git a/dev/solver_diagnostic.txt b/dev/solver_diagnostic.txt new file mode 100644 index 000000000..e4c152b1f --- /dev/null +++ b/dev/solver_diagnostic.txt @@ -0,0 +1,1163 @@ +**************************************************************** +* Begin Solver Diagnostic Results * +* * +* ''solver #'' refers to below solver descriptors * +* * +* ''iters'' refers to iterations taken * +* * +* ''op complexity'' refers to operator complexity * +* * +* ''work per DOA'' refers to work per digit of * +* accuracy to solve the algebraic system, i.e. it * +* measures the overall efficiency of the solver * +**************************************************************** + + + solver # | iters | op complexity | work per DOA +------------------------------------------------- + 1 | err | err | err + 2 | err | err | err + 3 | err | err | err + 4 | err | err | err + 5 | err | err | err + 6 | err | err | err + 7 | err | err | err + 8 | err | err | err + 9 | err | err | err + 10 | err | err | err + 11 | err | err | err + 12 | err | err | err + 13 | err | err | err + 14 | err | err | err + 15 | err | err | err + 16 | err | err | err + 17 | err | err | err + 18 | err | err | err + 19 | err | err | err + 20 | err | err | err + 21 | err | err | err + 22 | err | err | err + 23 | err | err | err + 24 | err | err | err + 25 | err | err | err + 26 | err | err | err + 27 | err | err | err + 28 | err | err | err + 29 | err | err | err + 30 | err | err | err + 31 | err | err | err + 32 | err | err | err + 33 | err | err | err + 34 | err | err | err + 35 | err | err | err + 36 | err | err | err + 37 | err | err | err + 38 | err | err | err + 39 | err | err | err + 40 | err | err | err + 41 | err | err | err + 42 | err | err | err + 43 | err | err | err + 44 | err | err | err + 45 | err | err | err + 46 | err | err | err + 47 | err | err | err + 48 | err | err | err + 49 | err | err | err + 50 | err | err | err + 51 | err | err | err + 52 | err | err | err + 53 | err | err | err + 54 | err | err | err + 55 | err | err | err + 56 | err | err | err + 57 | err | err | err + 58 | err | err | err + 59 | err | err | err + 60 | err | err | err + +**************************************************************** +* Begin Solver Descriptors +* Solver used is smoothed_aggregation_solver( ) +**************************************************************** + +Solver Descriptor 1 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = jacobi + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None] + +Solver Descriptor 2 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 3 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 4 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 5 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 6 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 7 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 8 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 9 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 10 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = jacobi + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 11 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = jacobi + improve_candidates = None + +Solver Descriptor 12 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 13 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 14 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = jacobi + improve_candidates = None + +Solver Descriptor 15 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 16 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 17 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 18 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 19 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 20 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = jacobi + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 21 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = jacobi + improve_candidates = None + +Solver Descriptor 22 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 23 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 24 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 25 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 26 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 27 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 28 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 29 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = jacobi + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 30 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 31 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 32 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = jacobi + improve_candidates = None + +Solver Descriptor 33 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 34 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 35 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 36 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 37 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 38 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 39 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 40 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('symmetric', {'theta': 0.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 41 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = jacobi + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 42 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = jacobi + improve_candidates = None + +Solver Descriptor 43 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 44 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 45 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 46 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 47 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 48 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 49 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 50 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 51 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = jacobi + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 52 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = jacobi + improve_candidates = None + +Solver Descriptor 53 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 54 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('jacobi', {'filter': True, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 55 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 56 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 57 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 58 + Solve phase arguments: + cycle = V + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}) + improve_candidates = None + +Solver Descriptor 59 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None] + +Solver Descriptor 60 + Solve phase arguments: + cycle = W + krylov accel = cg + tol = 1e-08 + maxiter = 300 + Setup phase arguments: + max_levels = 15 + max_coarse = 300 + coarse_solver = pinv + presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}) + test + strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0}) + aggregate = standard + smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'}) + improve_candidates = None + diff --git a/dev/solver_diagnostics.py b/dev/solver_diagnostics.py new file mode 100644 index 000000000..b96eb53ee --- /dev/null +++ b/dev/solver_diagnostics.py @@ -0,0 +1,655 @@ +import numpy as np +import scipy.sparse as sparse +import pyamg + + +def solver_diagnostics( + A, + solver=pyamg.smoothed_aggregation_solver, + fname='solver_diagnostic', + definiteness=None, + symmetry=None, + strength_list=None, + aggregate_list=None, + smooth_list=None, + improve_candidates_list=None, + max_levels_list=None, + cycle_list=None, + krylov_list=None, + prepostsmoother_list=None, + B_list=None, + coarse_size_list=None): + ''' + Try many different different parameter combinations for + smoothed_aggregation_solver(...). The goal is to find appropriate SA + parameter settings for the arbitrary matrix problem A x = 0 using a + random initial guess. + + Every combination of the input parameter lists is used to construct and + test an SA solver. Thus, be wary of the total number of solvers possible! + For example for an SPD CSR matrix, the default parameter lists generate 60 + different smoothed aggregation solvers. + + Symmetry and definiteness are automatically detected, but it is safest to + manually set these parameters through the ``definiteness" and ``symmetry" + parameters. + + Parameters + ---------- + A : {csr_matrix, bsr_matrix} + Sparse NxN matrix in CSR or BSR format + + solver : {smoothed_aggregation_solver, rootnode_solver} + Solver to run diagnostic on. Currently, these two solvers are supported. + + fname : {string} + File name where the diagnostic results are dumped + + Default: solver_diagnostic.txt + + definiteness : {string} + 'positive' denotes positive definiteness + 'indefinite' denotes indefiniteness + + Default: detected with a few iterations of Arnoldi iteration + + symmetry : {string} + 'hermitian' or 'nonsymmetric', denoting the symmetry of the matrix + + Default: detected by testing if A induces an inner-product + + strength_list : {list} + List of various parameter choices for the strength argument sent to solver(...) + + Default: [('symmetric', {'theta' : 0.0}), + ('evolution', {'k':2, 'proj_type':'l2', 'epsilon':2.0}), + ('evolution', {'k':2, 'proj_type':'l2', 'epsilon':4.0})] + + aggregate_list : {list} + List of various parameter choices for the aggregate argument sent to solver(...) + + Default: ['standard'] + + smooth_list : {list} + List of various parameter choices for the smooth argument sent to solver(...) + + Default depends on the symmetry and definiteness parameters: + if definiteness == 'positive' and (symmetry=='hermitian' or symmetry=='symmetric'): + ['jacobi', ('jacobi', {'filter' : True, 'weighting' : 'local'}), + ('energy',{'krylov':'cg','maxiter':2, 'degree':1, 'weighting':'local'}), + ('energy',{'krylov':'cg','maxiter':3, 'degree':2, 'weighting':'local'}), + ('energy',{'krylov':'cg','maxiter':4, 'degree':3, 'weighting':'local'})] + if definiteness == 'indefinite' or symmetry=='nonsymmetric': + [('energy',{'krylov':'gmres','maxiter':2,'degree':1,'weighting':'local'}), + ('energy',{'krylov':'gmres','maxiter':3,'degree':2,'weighting':'local'}), + ('energy',{'krylov':'gmres','maxiter':3,'degree':3,'weighting':'local'})] + + improve_candidates_list : {list} + List of various parameter choices for the improve_candidates argument sent to solver(...) + + Default: ['default', None] + + max_levels_list : {list} + List of various parameter choices for the max_levels argument sent to solver(...) + + Default: [25] + + cycle_list : {list} + List of various parameter choices for the cycle argument sent to solver.solve() + + Default: ['V', 'W'] + + krylov_list : {list} + List of various parameter choices for the krylov argument sent to + solver.solve(). Basic form is (string, dict), where the string is a + Krylov descriptor, e.g., 'cg' or 'gmres', and dict is a dictionary of + parameters like tol and maxiter. The dictionary dict may be empty. + + Default depends on the symmetry and definiteness parameters: + if symmetry == 'nonsymmetric' or definiteness == 'indefinite': + [('gmres', {'tol':1e-8, 'maxiter':300})] + else: + [('cg', {'tol':1e-8, 'maxiter':300})] + + prepostsmoother_list : {list} + List of various parameter choices for the presmoother and postsmoother + arguments sent to solver(...). Basic form is + [ (presmoother_descriptor, postsmoother_descriptor), ...]. + + Default depends on the symmetry parameter: + if symmetry == 'nonsymmetric' or definiteness == 'indefinite': + [ (('gauss_seidel_nr', {'sweep':'symmetric', 'iterations':2}), + ('gauss_seidel_nr', {'sweep':'symmetric', 'iterations':2})) ] + else: + [ (('block_gauss_seidel',{'sweep':'symmetric','iterations':1}), + ('block_gauss_seidel',{'sweep':'symmetric','iterations':1})) ] + + B_list : {list} + List of various B parameter choices for the B and BH arguments sent to + solver(...). Basic form is [ (B, BH, string), ...]. B is a vector of + left near null-space modes used to generate prolongation, BH is a + vector of right near null-space modes used to generate restriction, and + string is a python command(s) that can generate your particular B and + BH choice. B and BH must have a row-size equal to the dimensionality + of A. string is only used in the automatically generated test script. + + Default depends on whether A is BSR: + if A is CSR: + B_list = [(ones((A.shape[0],1)), ones((A.shape[0],1)), 'B, BH are all ones')] + if A is BSR: + bsize = A.blocksize[0] + B_list = [(ones((A.shape[0],1)), ones((A.shape[0],1)), 'B, BH are all ones'), + (kron(ones((A.shape[0]/bsize,1)), numpy.eye(bsize)), + kron(ones((A.shape[0]/bsize,1)), numpy.eye(bsize)), + 'B = kron(ones((A.shape[0]/A.blocksize[0],1), dtype=A.dtype), + eye(A.blocksize[0])); BH = B.copy()')] + + coarse_size_list : {list} + List of various tuples containing pairs of the (max_coarse, coarse_solver) + parameters sent to solver(...). + + Default: [ (300, 'pinv') ] + + Notes + ----- + Only smoothed_aggregation_solver(...) and rootnode_solver(...) are + supported. The Ruge-Stuben solver framework is not used. + + 60 total solvers are generated by the defaults for CSR SPD matrices. For + BSR SPD matrices, 120 total solvers are generated by the defaults. A + somewhat smaller number of total solvers is generated if the matrix is + indefinite or nonsymmetric. Every combination of the parameter lists is + attempted. + + Generally, there are two types of parameter lists passed to this function. + Type 1 includes: cycle_list, strength_list, aggregate_list, smooth_list, + krylov_list, improve_candidates_list, max_levels_list + ------------------------------------------- + Here, you pass in a list of different parameters, e.g., + cycle_list=['V','W']. + + Type 2 includes: B_list, coarse_size_list, prepostsmoother_list + ------------------------------------------- + This is similar to Type 1, only these represent lists of + pairs of parameters, e.g., + coarse_size_list=[ (300, 'pinv'), (5000, 'splu')], + where coarse size_list is of the form + [ (max_coarse, coarse_solver), ...]. + + For detailed info on each of these parameter lists, see above. + + Returns + ------- + Two files are written: + (1) fname + ".py" + Use the function defined here to generate and run the best + smoothed aggregation method found. The only argument taken + is a BSR/CSR matrix. + (2) fname + ".txt" + This file outputs the solver profile for each method + tried in a sorted table listing the best solver first. + The detailed solver descriptions then follow the table. + + See Also + -------- + smoothed_aggregation_solver + + Examples + -------- + >>> from pyamg import gallery + >>> from solver_diagnostics import * + >>> A = gallery.poisson( (50,50), format='csr') + >>> solver_diagnostics(A, fname='isotropic_diffusion_diagnostics.txt', cycle_list=['V']) + + ''' + + ## + # Preprocess A + if not (sparse.isspmatrix_csr(A) or sparse.isspmatrix_bsr(A)): + try: + A = sparse.csr_matrix(A) + print('Implicit conversion of A to CSR') + except BaseException: + raise TypeError('Argument A must have type csr_matrix or bsr_matrix,\ + or be convertible to csr_matrix') + # + A = A.asfptype() + # + if A.shape[0] != A.shape[1]: + raise ValueError('expected square matrix') + + print("\nSearching for optimal smoothed aggregation method for (%d,%d) matrix" % A.shape) + print(" ...") + + ## + # Detect symmetry + if symmetry is None: + if pyamg.util.linalg.ishermitian(A, fast_check=True): + symmetry = 'hermitian' + else: + symmetry = 'nonsymmetric' + ## + print(" Detected a " + symmetry + " matrix") + else: + print(" User specified a " + symmetry + " matrix") + + ## + # Detect definiteness + if definiteness is None: + [EVect, Lambda, H, V, breakdown_flag] = pyamg.util.linalg._approximate_eigenvalues( + A, 1e-6, 40) + if Lambda.min() < 0.0: + definiteness = 'indefinite' + print(" Detected indefiniteness") + else: + definiteness = 'positive' + print(" Detected positive definiteness") + else: + print(" User specified definiteness as " + definiteness) + + ## + # Default B are (1) a vector of all ones, and + # (2) if A is BSR, the constant for each variable + if B_list is None: + B_list = [(np.ones((A.shape[0], 1), dtype=A.dtype), + np.ones((A.shape[0], 1), dtype=A.dtype), + 'B = ones((A.shape[0],1), dtype=A.dtype); BH = B.copy()')] + + if sparse.isspmatrix_bsr(A) and A.blocksize[0] > 1: + bsize = A.blocksize[0] + B_list.append( + (np.kron(np.ones((A.shape[0] / bsize, 1), dtype=A.dtype), np.eye(bsize)), + np.kron(np.ones((A.shape[0] / bsize, 1), dtype=A.dtype), np.eye(bsize)), + 'B = kron(ones((A.shape[0]/A.blocksize[0],1), dtype=A.dtype), eye(A.blocksize[0])); BH = B.copy()')) + + ## + # Default is to try V- and W-cycles + if cycle_list is None: + cycle_list = ['V', 'W'] + + ## + # Default strength of connection values + if strength_list is None: + strength_list = [ + ('symmetric', { + 'theta': 0.0}), ('evolution', { + 'k': 2, 'proj_type': 'l2', 'epsilon': 2.0}), ('evolution', { + 'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})] + + ## + # Default aggregation strategies + if aggregate_list is None: + aggregate_list = ['standard'] + + ## + # Default prolongation smoothers + if smooth_list is None: + if definiteness == 'positive' and ( + symmetry == 'hermitian' or symmetry == 'symmetric'): + if solver.__name__ == 'smoothed_aggregation_solver': + smooth_list = [ + 'jacobi', ('jacobi', { + 'filter': True, 'weighting': 'local'})] + else: + smooth_list = [] + ## + smooth_list.append( + ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})) + smooth_list.append( + ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})) + smooth_list.append( + ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})) + elif definiteness == 'indefinite' or symmetry == 'nonsymmetric': + smooth_list = [ + ('energy', { + 'krylov': 'gmres', 'maxiter': 2, 'degree': 1, 'weighting': 'local'}), ('energy', { + 'krylov': 'gmres', 'maxiter': 3, 'degree': 2, 'weighting': 'local'}), ('energy', { + 'krylov': 'gmres', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})] + else: + raise ValueError('invalid string for definiteness and/or symmetry') + + ## + # Default pre- and postsmoothers + if prepostsmoother_list is None: + if symmetry == 'nonsymmetric' or definiteness == 'indefinite': + prepostsmoother_list = [ + (('gauss_seidel_nr', { + 'sweep': 'symmetric', 'iterations': 2}), ('gauss_seidel_nr', { + 'sweep': 'symmetric', 'iterations': 2}))] + else: + prepostsmoother_list = [ + (('block_gauss_seidel', { + 'sweep': 'symmetric', 'iterations': 1}), ('block_gauss_seidel', { + 'sweep': 'symmetric', 'iterations': 1}))] + + ## + # Default Krylov wrapper + if krylov_list is None: + if symmetry == 'nonsymmetric' or definiteness == 'indefinite': + krylov_list = [('gmres', {'tol': 1e-8, 'maxiter': 300})] + else: + krylov_list = [('cg', {'tol': 1e-8, 'maxiter': 300})] + + ## + # Default improve_candidates + if improve_candidates_list is None: + if symmetry == 'nonsymmetric' or definiteness == 'indefinite': + improve_candidates_list = [ + [('gauss_seidel_nr', {'sweep': 'symmetric', 'iterations': 4}), None], None] + else: + improve_candidates_list = [ + [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None], None] + + ## + # Default basic solver parameters + if max_levels_list is None: + max_levels_list = [15] + if coarse_size_list is None: + coarse_size_list = [(300, 'pinv')] + + ## + # Setup for ensuing numerical tests + # The results array will hold in each row, three values: + # iterations, operator complexity, and work per digit of accuracy + num_test = len(cycle_list) * len(strength_list) * len(aggregate_list) * len(smooth_list) * \ + len(krylov_list) * len(improve_candidates_list) * len(max_levels_list) * len(B_list) * \ + len(coarse_size_list) * len(prepostsmoother_list) + results = np.zeros((num_test, 3)) + solver_descriptors = [] + solver_args = [] + + ## + # Zero RHS and random initial guess + np.random.seed(0) + b = np.zeros((A.shape[0], 1), dtype=A.dtype) + x0 = np.random.rand(A.shape[0], 1) + if A.dtype == complex: + x0 += 1.0j * np.random.rand(A.shape[0], 1) + + ## + # Begin loops over parameter choices + print(" ...") + counter = -1 + for cycle in cycle_list: + for krylov in krylov_list: + for max_levels in max_levels_list: + for max_coarse, coarse_solver in coarse_size_list: + for presmoother, postsmoother in prepostsmoother_list: + for B_index in range(len(B_list)): + for strength in strength_list: + for aggregate in aggregate_list: + for smooth in smooth_list: + for improve_candidates in improve_candidates_list: + + counter += 1 + print(" Test %d out of %d" % (counter + 1, num_test)) + + ## + # Grab B vectors + B, BH, Bdescriptor = B_list[B_index] + + ## + # Store this solver setup + if 'tol' in krylov[1]: + tol = krylov[1]['tol'] + else: + tol = 1e-6 + if 'maxiter' in krylov[1]: + maxiter = krylov[1]['maxiter'] + else: + maxiter = 300 + ## + descriptor = ' Solve phase arguments:' + '\n' \ + ' cycle = ' + str(cycle) + '\n' \ + ' krylov accel = ' + str(krylov[0]) + '\n' \ + ' tol = ' + str(tol) + '\n' \ + ' maxiter = ' + str(maxiter) + '\n'\ + ' Setup phase arguments:' + '\n' \ + ' max_levels = ' + str(max_levels) + '\n' \ + ' max_coarse = ' + str(max_coarse) + '\n' \ + ' coarse_solver = ' + str(coarse_solver) + '\n'\ + ' presmoother = ' + str(presmoother) + '\n' \ + ' postsmoother = ' + str(postsmoother) + '\n'\ + ' ' + Bdescriptor + '\n' \ + ' strength = ' + str(strength) + '\n' \ + ' aggregate = ' + str(aggregate) + '\n' \ + ' smooth = ' + str(smooth) + '\n' \ + ' improve_candidates = ' + str(improve_candidates) + solver_descriptors.append( + descriptor) + solver_args.append( + { + 'cycle': cycle, + 'accel': str( + krylov[0]), + 'tol': tol, + 'maxiter': maxiter, + 'max_levels': max_levels, + 'max_coarse': max_coarse, + 'coarse_solver': coarse_solver, + 'B_index': B_index, + 'presmoother': presmoother, + 'postsmoother': postsmoother, + 'strength': strength, + 'aggregate': aggregate, + 'smooth': smooth, + 'improve_candidates': improve_candidates}) + + ## + # Construct solver + try: + sa = solver( + A, + B=B, + BH=BH, + strength=strength, + smooth=smooth, + improve_candidates=improve_candidates, + aggregate=aggregate, + presmoother=presmoother, + max_levels=max_levels, + postsmoother=postsmoother, + max_coarse=max_coarse, + coarse_solver=coarse_solver) + + ## + # Solve system + residuals = [] + x = sa.solve( + b, + x0=x0, + accel=krylov[0], + cycle=cycle, + tol=tol, + maxiter=maxiter, + residuals=residuals) + print(np.linalg.norm(b - A * x)) + + # Store results: iters, operator complexity, and + # work per digit-of-accuracy + results[counter, 0] = len( + residuals) + results[counter, + 1] = sa.operator_complexity() + resid_rate = (residuals[-1] / residuals[0]) **\ + (1.0 / (len(residuals) - 1.)) + results[counter, 2] = sa.cycle_complexity( + ) / abs(np.log10(resid_rate)) + + except BaseException: + descriptor_indented = ' ' + \ + descriptor.replace('\n', '\n ') + print(" --> Failed this test") + print(" --> Solver descriptor is...") + print(descriptor_indented) + results[counter, :] = np.inf + ## + # Sort results and solver_descriptors according to work-per-doa + indys = np.argsort(results[:, 2]) + results = results[indys, :] + solver_descriptors = list(np.array(solver_descriptors)[indys]) + solver_args = list(np.array(solver_args)[indys]) + + ## + # Create table from results and print to file + table = [['solver #', 'iters', 'op complexity', 'work per DOA']] + for i in range(results.shape[0]): + if (results[i, :] == np.inf).all(): + # in this case the test failed... + table.append(['%d' % (i + 1), 'err', 'err', 'err']) + else: + table.append(['%d' % + (i + 1), '%d' % + results[i, 0], '%1.1f' % + results[i, 1], '%1.1f' % + results[i, 2]]) + # + fptr = open(fname + '.txt', 'w') + fptr.write( + '****************************************************************\n' + + '* Begin Solver Diagnostic Results *\n' + + '* *\n' + + '* \'\'solver #\'\' refers to below solver descriptors *\n' + + '* *\n' + + '* \'\'iters\'\' refers to iterations taken *\n' + + '* *\n' + + '* \'\'op complexity\'\' refers to operator complexity *\n' + + '* *\n' + + '* \'\'work per DOA\'\' refers to work per digit of *\n' + + '* accuracy to solve the algebraic system, i.e. it *\n' + + '* measures the overall efficiency of the solver *\n' + + '****************************************************************\n\n') + fptr.write(pyamg.util.utils.print_table(table)) + + ## + # Now print each solver descriptor to file + fptr.write( + '\n****************************************************************\n' + + '* Begin Solver Descriptors \n' + + '* Solver used is ' + + solver.__name__ + + '( ) \n' + + '****************************************************************\n\n') + + for i in range(len(solver_descriptors)): + fptr.write('Solver Descriptor %d\n' % (i + 1)) + fptr.write(solver_descriptors[i]) + fptr.write(' \n \n') + + fptr.close() + + ## + # Now write a function definition file that generates the "best" solver + fptr = open(fname + '.py', 'w') + # Helper function for file writing + + def to_string(a): + if isinstance(a, type((1,))): + return(str(a)) + elif isinstance(a, type('s')): + return("\"%s\"" % a) + else: + return str(a) + # + fptr.write( + '#######################################################################\n') + fptr.write( + '# Function definition automatically generated by solver_diagnostics.py\n') + fptr.write('#\n') + fptr.write('# Use the function defined here to generate and run the best\n') + fptr.write('# smoothed aggregation method found by solver_diagnostics(...).\n') + fptr.write('# The only argument taken is a CSR/BSR matrix.\n') + fptr.write('#\n') + fptr.write('# To run: >>> # User must load/generate CSR/BSR matrix A\n') + fptr.write('# >>> from ' + fname + ' import ' + fname + '\n') + fptr.write('# >>> ' + fname + '(A)' + '\n') + fptr.write( + '#######################################################################\n\n') + fptr.write('from pyamg import ' + solver.__name__ + '\n') + fptr.write('from pyamg.util.linalg import norm\n') + fptr.write('from numpy import ones, array, arange, zeros, abs, random\n') + fptr.write('from scipy import rand, ravel, log10, kron, eye\n') + fptr.write('from scipy.io import loadmat\n') + fptr.write('from scipy.sparse import isspmatrix_bsr, isspmatrix_csr\n') + fptr.write('import pylab\n\n') + fptr.write('def ' + fname + '(A):\n') + fptr.write(' ##\n # Generate B\n') + fptr.write(' ' + B_list[B_index][2] + '\n\n') + fptr.write(' ##\n # Random initial guess, zero right-hand side\n') + fptr.write(' random.seed(0)\n') + fptr.write(' b = zeros((A.shape[0],1))\n') + fptr.write(' x0 = rand(A.shape[0],1)\n\n') + fptr.write(' ##\n # Create solver\n') + fptr.write( + ' ml = ' + + solver.__name__ + + '(A, B=B, BH=BH,\n' + + ' strength=%s,\n' % + to_string( + solver_args[0]['strength']) + + ' smooth=%s,\n' % + to_string( + solver_args[0]['smooth']) + + ' improve_candidates=%s,\n' % + to_string( + solver_args[0]['improve_candidates']) + + ' aggregate=%s,\n' % + to_string( + solver_args[0]['aggregate']) + + ' presmoother=%s,\n' % + to_string( + solver_args[0]['presmoother']) + + ' postsmoother=%s,\n' % + to_string( + solver_args[0]['postsmoother']) + + ' max_levels=%s,\n' % + to_string( + solver_args[0]['max_levels']) + + ' max_coarse=%s,\n' % + to_string( + solver_args[0]['max_coarse']) + + ' coarse_solver=%s)\n\n' % + to_string( + solver_args[0]['coarse_solver'])) + fptr.write(' ##\n # Solve system\n') + fptr.write(' res = []\n') + fptr.write( + ' x = ml.solve(b, x0=x0, tol=%s, residuals=res, accel=%s, maxiter=%s, cycle=%s)\n' % + (to_string( + solver_args[0]['tol']), to_string( + solver_args[0]['accel']), to_string( + solver_args[0]['maxiter']), to_string( + solver_args[0]['cycle']))) + fptr.write(' res_rate = (res[-1]/res[0])**(1.0/(len(res)-1.))\n') + fptr.write(' normr0 = norm(ravel(b) - ravel(A*x0))\n') + fptr.write(' print(" ")\n') + fptr.write(' print(ml)\n') + fptr.write(" print(\"System size: \" + str(A.shape))\n") + fptr.write(" print(\"Avg. Resid Reduction: %1.2f\" % res_rate)\n") + fptr.write(" print(\"Iterations: %d\" % len(res))\n") + fptr.write( + " print(\"Operator Complexity: %1.2f\" % ml.operator_complexity())\n") + fptr.write( + " print(\"Work per DOA: %1.2f\" % (ml.cycle_complexity()/abs(log10(res_rate))))\n") + fptr.write( + " print(\"Relative residual norm: %1.2e\" % (norm(ravel(b) - ravel(A*x))/normr0))\n\n") + fptr.write(' ##\n # Plot residual history\n') + fptr.write(' pylab.semilogy(array(res)/normr0)\n') + fptr.write(' pylab.title(\'Residual Histories\')\n') + fptr.write(' pylab.xlabel(\'Iteration\')\n') + fptr.write(' pylab.ylabel(\'Relative Residual Norm\')\n') + fptr.write(' pylab.show()\n\n') + # Close file pointer + fptr.close() + + print(" ...") + print(" --> Diagnostic Results located in " + fname + '.txt') + print(" ...") + print(" --> See automatically generated function definition\n" + + " ./" + fname + ".py.\n\n" + + " Use the function defined here to generate and run the best\n" + + " smoothed aggregation method found. The only argument taken\n" + + " is a CSR/BSR matrix.\n\n" + + " To run: >>> # User must load/generate CSR/BSR matrix A\n" + + " >>> from " + fname + " import " + fname + "\n" + + " >>> " + fname + "(A)") From 3eecaedcae9999ee0bc321490e22583a4afd7394 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Thu, 4 Feb 2021 17:43:39 +1100 Subject: [PATCH 18/29] (BUG) moved surfe warning to only occur if surfe is used --- .../modelling/core/geological_model.py | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/LoopStructural/modelling/core/geological_model.py b/LoopStructural/modelling/core/geological_model.py index a44691663..27d2eade2 100644 --- a/LoopStructural/modelling/core/geological_model.py +++ b/LoopStructural/modelling/core/geological_model.py @@ -13,14 +13,6 @@ from LoopStructural.interpolators.piecewiselinear_interpolator import \ PiecewiseLinearInterpolator as PLI -try: - from LoopStructural.interpolators.surfe_wrapper import \ - SurfeRBFInterpolator as Surfe - - surfe = True - -except ImportError: - surfe = False from LoopStructural.interpolators.structured_grid import StructuredGrid from LoopStructural.interpolators.structured_tetra import TetMesh @@ -39,8 +31,7 @@ from LoopStructural.utils import getLogger, log_to_file logger = getLogger(__name__) -if not surfe: - logger.warning("Cannot import Surfe") + def _calculate_average_intersection(series_builder, fold_frame, fold, @@ -543,6 +534,18 @@ def get_interpolator(self, interpolatortype='PLI', nelements=1e5, return DFI(mesh, kwargs['fold']) if interpolatortype == 'Surfe' or interpolatortype == 'surfe' and \ surfe: + # move import of surfe to where we actually try and use it + try: + from LoopStructural.interpolators.surfe_wrapper import \ + SurfeRBFInterpolator as Surfe + + surfe = True + + except ImportError: + surfe = False + if not surfe: + logger.warning("Cannot import Surfe, try another interpolator") + raise ImportError method = kwargs.get('method', 'single_surface') logger.info("Using surfe interpolator") return Surfe(method) @@ -1150,7 +1153,7 @@ def create_and_add_fault(self, horizontal_radius=fault_extent/self.scale_factor, vertical_radius=fault_vectical_radius/self.scale_factor ) - fault_frame_builder.set_mesh_geometry(0.1) + fault_frame_builder.set_mesh_geometry(kwargs.get('fault_buffer',0.1)) # fault_frame_builder.add_data_from_data_frame(fault_frame_data) # check if this fault overprint any existing faults exist in the stack overprinted = kwargs.get('overprinted', []) @@ -1167,6 +1170,7 @@ def create_and_add_fault(self, fault = FaultSegment(fault_frame, displacement=displacement_scaled, **kwargs) + fault.builder=fault_frame_builder for f in reversed(self.features): if f.type == 'unconformity': fault.add_region(lambda pos: f.evaluate_value(pos) <= 0) @@ -1438,3 +1442,23 @@ def evaluate_feature_gradient(self, feature_name, xyz, scale=True): return feature.evaluate_gradient(scaled_xyz) else: return np.zeros(xyz.shape[0]) + + def update(self,verbose=False): + if verbose: + nfeatures = 0 + for f in self.features: + if f.type=='fault': + nfeatures+=3 + else: + nfeatures+=1 + print('Updating geological model. There are: \n' + '{} geological features that need to be interpolated\n'.format(nfeatures) + ) + from tqdm import tqdm + import time + start = time.time() + for f in tqdm(self.features): + f.builder.update() + if verbose: + print("Model update took: {} seconds".format(time.time()-start)) + From fee5d190d0ba5e11dbab360ec5e31c329abcbac1 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Thu, 4 Feb 2021 17:44:03 +1100 Subject: [PATCH 19/29] (BUG) no solution now tells which scalar field --- LoopStructural/interpolators/discrete_interpolator.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/LoopStructural/interpolators/discrete_interpolator.py b/LoopStructural/interpolators/discrete_interpolator.py index 5d84ef21c..e01bb707d 100644 --- a/LoopStructural/interpolators/discrete_interpolator.py +++ b/LoopStructural/interpolators/discrete_interpolator.py @@ -157,6 +157,8 @@ def add_constraints_to_least_squares(self, A, B, idc, name='undefined'): B = np.array(B) idc = np.array(idc) nr = A.shape[0] + #logger.debug('Adding constraints to interpolator: {} {} {}'.format(A.shape[0])) + # print(A.shape,B.shape,idc.shape) if A.shape != idc.shape: return @@ -521,7 +523,7 @@ def _solve(self, solver='cg', **kwargs): logger.warning("Solver not run, no scalar field") # if solution is all 0, probably didn't work if np.all(self.c[self.region] == 0): - logger.warning("No solution, scalar field 0. Add more data.") + logger.warning("No solution, {} scalar field 0. Add more data.".format(self.propertyname)) def update(self): """ From 92effb56f02e0cac0c0ff476f9d9d776c6d75bf1 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 5 Feb 2021 12:56:50 +1100 Subject: [PATCH 20/29] (FEATURE) adding progress bar --- .../modelling/core/geological_model.py | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/LoopStructural/modelling/core/geological_model.py b/LoopStructural/modelling/core/geological_model.py index 27d2eade2..6f9b80949 100644 --- a/LoopStructural/modelling/core/geological_model.py +++ b/LoopStructural/modelling/core/geological_model.py @@ -1443,22 +1443,41 @@ def evaluate_feature_gradient(self, feature_name, xyz, scale=True): else: return np.zeros(xyz.shape[0]) - def update(self,verbose=False): - if verbose: - nfeatures = 0 - for f in self.features: - if f.type=='fault': - nfeatures+=3 - else: - nfeatures+=1 + def update(self,verbose=False,progressbar=True): + total_dof = 0 + nfeatures = 0 + for f in self.features: + if f.type=='fault': + nfeatures+=3 + total_dof+=f[0].interpolator.nx*3 + else: + nfeatures+=1 + total_dof+=f.interpolator.nx + if verbose==True: print('Updating geological model. There are: \n' '{} geological features that need to be interpolated\n'.format(nfeatures) ) + from tqdm import tqdm import time start = time.time() - for f in tqdm(self.features): - f.builder.update() + sizecounter = 0 + + # Load tqdm with size counter instead of file counter + with tqdm(total=total_dof) as pbar: + buf = 1 + for f in self.features: + pbar.set_description('Interpolating {}'.format(f.name)) + if f.type == 'fault': + for i in range(3): + f[i].builder.update() + buf+=f[i].interpolator.nx + else: + f.builder.update() + buf+=f.interpolator.nx + pbar.update(buf) + + if verbose: print("Model update took: {} seconds".format(time.time()-start)) From f7628ad57538168422c122d830f6c1837783a291 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 5 Feb 2021 12:57:14 +1100 Subject: [PATCH 21/29] (BUG) fixed bug where args for frame 1 were missed --- LoopStructural/modelling/features/geological_feature.py | 1 - LoopStructural/modelling/features/structural_frame_builder.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/LoopStructural/modelling/features/geological_feature.py b/LoopStructural/modelling/features/geological_feature.py index ee89b522d..160cc2545 100644 --- a/LoopStructural/modelling/features/geological_feature.py +++ b/LoopStructural/modelling/features/geological_feature.py @@ -132,7 +132,6 @@ def evaluate_value(self, evaluation_points): # apply faulting after working out which regions are visible if self.faults_enabled: for f in self.faults: - print(f.name, self.name) evaluation_points = f.apply_to_points(evaluation_points) v[mask] = self.interpolator.evaluate_value(evaluation_points[mask, :]) return v diff --git a/LoopStructural/modelling/features/structural_frame_builder.py b/LoopStructural/modelling/features/structural_frame_builder.py index 11f139fa6..c4db20746 100644 --- a/LoopStructural/modelling/features/structural_frame_builder.py +++ b/LoopStructural/modelling/features/structural_frame_builder.py @@ -166,7 +166,7 @@ def build(self, w1=1., w2=1., w3=1., frame=StructuralFrame, **kwargs): self.builders[1].add_orthogonal_feature(gz_feature, gyxgz,step=step) gy_feature = self.builders[1].feature kwargs['regularisation'] = regularisation[1] - self.builders[2].build_arguments = kwargs + self.builders[1].build_arguments = kwargs if gy_feature is None: logger.warning( From 70b516314b010f5a0c76622d3161652daad50681 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 5 Feb 2021 14:33:21 +1100 Subject: [PATCH 22/29] (DOC) adding guide for faults --- .../interpolators/discrete_interpolator.py | 2 ++ LoopStructural/modelling/core/geological_model.py | 4 ++-- docs/source/user_guide/fault_modelling.rst | 6 ++++++ docs/source/user_guide/geological_model.rst | 15 +++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/LoopStructural/interpolators/discrete_interpolator.py b/LoopStructural/interpolators/discrete_interpolator.py index e01bb707d..f9a3cb6f0 100644 --- a/LoopStructural/interpolators/discrete_interpolator.py +++ b/LoopStructural/interpolators/discrete_interpolator.py @@ -483,6 +483,8 @@ def _solve(self, solver='cg', **kwargs): True if the interpolation is run """ + logger.info("Solving interpolation for {}".format(self.propertyname)) + self.c = np.zeros(self.support.n_nodes) self.c[:] = np.nan damp = True diff --git a/LoopStructural/modelling/core/geological_model.py b/LoopStructural/modelling/core/geological_model.py index 6f9b80949..62071cbeb 100644 --- a/LoopStructural/modelling/core/geological_model.py +++ b/LoopStructural/modelling/core/geological_model.py @@ -1450,7 +1450,7 @@ def update(self,verbose=False,progressbar=True): if f.type=='fault': nfeatures+=3 total_dof+=f[0].interpolator.nx*3 - else: + if f.type == 'series': nfeatures+=1 total_dof+=f.interpolator.nx if verbose==True: @@ -1472,7 +1472,7 @@ def update(self,verbose=False,progressbar=True): for i in range(3): f[i].builder.update() buf+=f[i].interpolator.nx - else: + if f.type == 'series': f.builder.update() buf+=f.interpolator.nx pbar.update(buf) diff --git a/docs/source/user_guide/fault_modelling.rst b/docs/source/user_guide/fault_modelling.rst index 6af0f2ff1..6993c0fbb 100644 --- a/docs/source/user_guide/fault_modelling.rst +++ b/docs/source/user_guide/fault_modelling.rst @@ -1,2 +1,8 @@ Fault modelling =============== + +Fault can be added into LoopStructural using the :meth:`LoopStructural.GeologicalModel.create_and_add_fault` function. + +.. code-block:: + model.create_and_add_fault() +In version 1.1 the interface for building \ No newline at end of file diff --git a/docs/source/user_guide/geological_model.rst b/docs/source/user_guide/geological_model.rst index 673af28af..88c56fd97 100644 --- a/docs/source/user_guide/geological_model.rst +++ b/docs/source/user_guide/geological_model.rst @@ -174,6 +174,21 @@ A GeologicalFeature can be extracted from the model either by name myfeature_by_index = model.features[0] myfeature_by_name = model.get_feature_by_name('myfeature') +Solving/Updating a geological model +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In version 1.1+ the implicit function representing a geological feature does not have to be solved to generate the model object. +The scalar field is solved on demand when the geological features are evaluated. +This means that parts of the geological model can be modified and only the older (features lower in the feature list) are updated. +All features in the model can be updated: + +.. code-block:: + + model.update(verbose=False) + +This will solve the implicit function for all features in the model and provide a progress bar. +The verbose flag provides additional information useful for debugging including the number of degrees of freedom in the system and the time taken to solve. + Evaluating a scalar field ~~~~~~~~~~~~~~~~~~~~~~~~~ From 8f512c8b5f4dd5d1aa3936badd49aef6129f5720 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 5 Feb 2021 16:09:10 +1100 Subject: [PATCH 23/29] (DOCS) adding fault param description --- docs/requirements.txt | 2 +- docs/source/user_guide/fault_modelling.rst | 48 +++++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index f9fade8bd..e213b2b8b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ -sphinx +sphinx==2.2.4 sphinx_gallery sphinxcontrib-bibtex sphinx_rtd_theme \ No newline at end of file diff --git a/docs/source/user_guide/fault_modelling.rst b/docs/source/user_guide/fault_modelling.rst index 6993c0fbb..7acb5e861 100644 --- a/docs/source/user_guide/fault_modelling.rst +++ b/docs/source/user_guide/fault_modelling.rst @@ -4,5 +4,49 @@ Fault modelling Fault can be added into LoopStructural using the :meth:`LoopStructural.GeologicalModel.create_and_add_fault` function. .. code-block:: - model.create_and_add_fault() -In version 1.1 the interface for building \ No newline at end of file + + model.create_and_add_fault(feature_name, + displacement, + fault_slip_vector=None, + fault_center = None, + fault_extent = None, + fault_influence = None, + fault_vectical_radius = None, + faultfunction = None, + **kwargs + ) + +In version 1.1 the additional arguments for the fault geometry were added. +Additional parameters can be specified to the interpolator including: + + + .. list-table:: Fault parameters + :widths: 25 75 + :header-rows: 1 + + * - Parameter + - Options + * - feature_name + - identifying string in the model dataframe + * - displacement + - magnitude of the displacement, or maximum displacement, + * - fault_slip_vector + - numpy array describing the fault slip + * - fault_center + - the center of the fault + * - fault_extent + - the radius of the fault ellipsoid parallel to fault surface and orthogonal to slip direction + * - fault_influence + - radius of ellipsoid orthogonal to fault + * - fault_vertical_radius + - fault ellipsoid radius in slip direction + * - faultfunction + - function describing the fault slip in the fault frame coordinates + + + +Fault function +-------------- + +The fault function describes the displacement magnitude of the fault relative to the fault frame coordinate. +A basic fault function is provided in LoopStructural. \ No newline at end of file From f4d74745e4c668cc9b7f10a9cf00f02e2b1aaef6 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Fri, 5 Feb 2021 16:09:29 +1100 Subject: [PATCH 24/29] (BUG) fixing fault builder for infinite faults --- .../modelling/core/geological_model.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/LoopStructural/modelling/core/geological_model.py b/LoopStructural/modelling/core/geological_model.py index 62071cbeb..ded444208 100644 --- a/LoopStructural/modelling/core/geological_model.py +++ b/LoopStructural/modelling/core/geological_model.py @@ -140,7 +140,7 @@ def __init__(self, origin, maximum, rescale=True, nsteps=(40, 40, 40), self.bounding_box[1, :] = self.maximum - self.origin self.bounding_box[1, :] = self.maximum - self.origin if rescale: - self.scale_factor = np.max(lengths) + self.scale_factor = np.max(lengths,dtype=float) logger.info('Rescaling model using scale factor {}'.format(self.scale_factor)) self._str+='Model rescale factor: {} \n'.format(self.scale_factor) self._str+='The model contains {} GeologicalFeatures \n'.format(len(self.features)) @@ -1103,7 +1103,8 @@ def create_and_add_fault(self, fault_center = None, fault_extent = None, fault_influence = None, - fault_vectical_radius = None, + fault_vectical_radius = None, + faultfunction=None, **kwargs): """ Parameters @@ -1145,13 +1146,19 @@ def create_and_add_fault(self, # the fault trace mask = np.logical_and(fault_frame_data['coord']==0,fault_frame_data['val']==0) fault_center = fault_frame_data.loc[mask,['X','Y','Z']].mean(axis=0).to_numpy() + if influence_distance: + influence_distance=fault_influence/self.scale_factor + if horizontal_radius: + horizontal_radius=fault_extent/self.scale_factor + if vertical_radius: + vertical_radius=fault_vectical_radius/self.scale_factor fault_frame_builder.create_data_from_geometry(fault_frame_data, self.scale(fault_center), fault_normal_vector, fault_slip_vector, - influence_distance=fault_influence/self.scale_factor, - horizontal_radius=fault_extent/self.scale_factor, - vertical_radius=fault_vectical_radius/self.scale_factor + influence_distance=fault_influence, + horizontal_radius=fault_extent, + vertical_radius=fault_vectical_radius ) fault_frame_builder.set_mesh_geometry(kwargs.get('fault_buffer',0.1)) # fault_frame_builder.add_data_from_data_frame(fault_frame_data) From f7d348a4dd071fdcf1b385f32aaa11204eae3d26 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Tue, 9 Feb 2021 10:56:04 +1100 Subject: [PATCH 25/29] (DEV) some bug fixes for fault geometry change --- .../modelling/core/geological_model.py | 21 ++++++++++++------- .../modelling/fault/fault_builder.py | 2 ++ .../modelling/features/geological_feature.py | 3 +++ .../modelling/features/structural_frame.py | 5 +---- LoopStructural/utils/map2loop.py | 2 +- .../visualisation/model_visualisation.py | 13 +++++++++++- 6 files changed, 32 insertions(+), 14 deletions(-) diff --git a/LoopStructural/modelling/core/geological_model.py b/LoopStructural/modelling/core/geological_model.py index ded444208..9949149ad 100644 --- a/LoopStructural/modelling/core/geological_model.py +++ b/LoopStructural/modelling/core/geological_model.py @@ -140,7 +140,7 @@ def __init__(self, origin, maximum, rescale=True, nsteps=(40, 40, 40), self.bounding_box[1, :] = self.maximum - self.origin self.bounding_box[1, :] = self.maximum - self.origin if rescale: - self.scale_factor = np.max(lengths,dtype=float) + self.scale_factor = float(np.max(lengths)) logger.info('Rescaling model using scale factor {}'.format(self.scale_factor)) self._str+='Model rescale factor: {} \n'.format(self.scale_factor) self._str+='The model contains {} GeologicalFeatures \n'.format(len(self.features)) @@ -1141,25 +1141,30 @@ def create_and_add_fault(self, mask = np.logical_and(fault_frame_data['coord']==1,~np.isnan(fault_frame_data['gz'])) if fault_slip_vector is None: fault_slip_vector = fault_frame_data.loc[mask,['gx','gy','gz']].mean(axis=0).to_numpy() + if fault_center is not None: + fault_center = self.scale(fault_center,inplace=False) if fault_center is None: # if we haven't defined a fault centre take the center of mass for lines assocaited with # the fault trace mask = np.logical_and(fault_frame_data['coord']==0,fault_frame_data['val']==0) fault_center = fault_frame_data.loc[mask,['X','Y','Z']].mean(axis=0).to_numpy() - if influence_distance: - influence_distance=fault_influence/self.scale_factor - if horizontal_radius: - horizontal_radius=fault_extent/self.scale_factor - if vertical_radius: - vertical_radius=fault_vectical_radius/self.scale_factor + if fault_influence: + fault_influence=fault_influence/self.scale_factor + if fault_extent: + fault_extent=fault_extent/self.scale_factor + if fault_vectical_radius: + fault_vectical_radius=fault_vectical_radius/self.scale_factor fault_frame_builder.create_data_from_geometry(fault_frame_data, - self.scale(fault_center), + fault_center, fault_normal_vector, fault_slip_vector, influence_distance=fault_influence, horizontal_radius=fault_extent, vertical_radius=fault_vectical_radius ) + if fault_influence == None or fault_extent == None or fault_vectical_radius == None: + fault_frame_builder.origin = self.origin + fault_frame_builder.maximum = self.maximum fault_frame_builder.set_mesh_geometry(kwargs.get('fault_buffer',0.1)) # fault_frame_builder.add_data_from_data_frame(fault_frame_data) # check if this fault overprint any existing faults exist in the stack diff --git a/LoopStructural/modelling/fault/fault_builder.py b/LoopStructural/modelling/fault/fault_builder.py index e30ae2010..a8cef99a2 100644 --- a/LoopStructural/modelling/fault/fault_builder.py +++ b/LoopStructural/modelling/fault/fault_builder.py @@ -51,6 +51,8 @@ def create_data_from_geometry(self, vertical_radius : double fault volume radius in the slip direction """ + normal_vector/=np.linalg.norm(normal_vector) + slip_vector/=np.linalg.norm(slip_vector) strike_vector = np.cross(normal_vector,slip_vector) fault_edges = np.zeros((2,3)) fault_tips = np.zeros((2,3)) diff --git a/LoopStructural/modelling/features/geological_feature.py b/LoopStructural/modelling/features/geological_feature.py index 160cc2545..57cff241e 100644 --- a/LoopStructural/modelling/features/geological_feature.py +++ b/LoopStructural/modelling/features/geological_feature.py @@ -120,6 +120,9 @@ def evaluate_value(self, evaluation_points): numpy array containing evaluated values """ + #TODO need to add a generic type checker for all methods + #if evaluation_points is not a numpy array try and convert + #otherwise error self.builder.up_to_date() # check if the points are within the display region v = np.zeros(evaluation_points.shape[0]) diff --git a/LoopStructural/modelling/features/structural_frame.py b/LoopStructural/modelling/features/structural_frame.py index ded2df05d..f398740c6 100644 --- a/LoopStructural/modelling/features/structural_frame.py +++ b/LoopStructural/modelling/features/structural_frame.py @@ -107,10 +107,7 @@ def evaluate_value(self, evaluation_points): v[:,1] = self.features[1].evaluate_value(evaluation_points) v[:,2] = self.features[2].evaluate_value(evaluation_points) return v - # return (self.features[0].evaluate_value(evaluation_points), - # self.features[1].evaluate_value(evaluation_points), - # self.features[2].evaluate_value(evaluation_points)) - + def evaluate_gradient(self, evaluation_points, i=None): """ Evaluate the gradient of the structural frame. diff --git a/LoopStructural/utils/map2loop.py b/LoopStructural/utils/map2loop.py index 63f933681..eb1e6a6a8 100644 --- a/LoopStructural/utils/map2loop.py +++ b/LoopStructural/utils/map2loop.py @@ -317,7 +317,7 @@ def build_model(m2l_data, skip_faults = False, unconformities=False, fault_param faults.append(model.create_and_add_fault(f, -m2l_data['max_displacement'][f], faultfunction='BaseFault', - fault_slip_vector=np.array([0,0,-1]), + fault_slip_vector=np.array([0.,0.,-1.]), fault_center=fault_center, fault_extent=fault_extent, fault_influence=fault_influence, diff --git a/LoopStructural/visualisation/model_visualisation.py b/LoopStructural/visualisation/model_visualisation.py index 41165ebf0..885132031 100644 --- a/LoopStructural/visualisation/model_visualisation.py +++ b/LoopStructural/visualisation/model_visualisation.py @@ -497,7 +497,18 @@ def add_fault_displacements(self, cmap = 'rainbow', **kwargs): vmin = kwargs.get('vmin', np.nanmin(vals)) vmax = kwargs.get('vmax', np.nanmax(vals)) surf.colourmap(cmap, range=(vmin, vmax)) - + + def add_fault_ellipse(self, faults=None, **kwargs): + from matplotlib.patches import Ellipse + for k, f in self.model.stratigraphic_column['faults'].items(): + center = self.model.rescale(f['FaultCenter']) + e = Ellipse((center[0],center[1]), + f['HorizontalRadius']*2, + f['InfluenceDistance']*2, + 360-f['FaultDipDirection'], + facecolor='None',edgecolor='k') + + self.ax.add_patch(e) def add_model_surfaces(self, faults = True, cmap=None, fault_colour='black',**kwargs): """Add surfaces for all of the interfaces in the model From 62030287a65d9b95cc837f50d861ade1a0cf0255 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Tue, 9 Feb 2021 10:58:26 +1100 Subject: [PATCH 26/29] (DEV) upgrading version, some fixes for sections --- LoopStructural/__init__.py | 2 +- .../visualisation/model_visualisation.py | 23 +- dev/visualisation check.ipynb | 6856 +++++++++++++++++ docs/source/user_guide/geological_model.rst | 1 + docs/source/user_guide/visualisation.rst | 131 + 5 files changed, 6998 insertions(+), 15 deletions(-) create mode 100644 dev/visualisation check.ipynb diff --git a/LoopStructural/__init__.py b/LoopStructural/__init__.py index 8b97e773a..a569b9019 100644 --- a/LoopStructural/__init__.py +++ b/LoopStructural/__init__.py @@ -31,7 +31,7 @@ ch.setFormatter(formatter) ch.setLevel(logging.WARNING) loggers = {} -__version__ = '1.0.5' +__version__ = '1.0.6-dev' from .modelling.core.geological_model import GeologicalModel from .visualisation.model_visualisation import LavaVuModelViewer from .visualisation.map_viewer import MapView diff --git a/LoopStructural/visualisation/model_visualisation.py b/LoopStructural/visualisation/model_visualisation.py index 41165ebf0..51ba8bdc0 100644 --- a/LoopStructural/visualisation/model_visualisation.py +++ b/LoopStructural/visualisation/model_visualisation.py @@ -147,29 +147,26 @@ def add_section(self, geological_feature=None, axis='x', value=None, **kwargs): ------- """ - print('aa') if axis == 'x': tri, yy, zz = create_surface(self.bounding_box[:, [1, 2]], self.nsteps[[1, 2]]) xx = np.zeros(zz.shape) if value is None: - xx[:] = np.nanmean(self.bounding_box[:, 0]) - else: - xx[:] = value + value = np.nanmean(self.bounding_box[:, 0]) + xx[:] = value if axis == 'y': tri, xx, zz = create_surface(self.bounding_box[:, [0, 2]], self.nsteps[[0, 2]]) yy = np.zeros(xx.shape) if value is None: - yy[:] = np.nanmean(self.bounding_box[:, 1]) - else: - yy[:] = value + value = np.nanmean(self.bounding_box[:, 1]) + yy[:] = value if axis == 'z': tri, xx, yy = create_surface(self.bounding_box[:, 0:2], self.nsteps[0:2]) zz = np.zeros(xx.shape) if value is None: - zz[:] = np.nanmean(self.bounding_box[:, 2]) - else: - zz[:] = value - name = kwargs.get('name', axis + '_slice') + value = np.nanmean(self.bounding_box[:, 2]) + zz[:] = value + name = kwargs.get('name', geological_feature.name) + name = '{}_section_at_{}_of_{}'.format(axis,value,name) colour = kwargs.get('colour', 'red') # create an array to evaluate the feature on for the section @@ -208,9 +205,7 @@ def add_section(self, geological_feature=None, axis='x', value=None, **kwargs): cmap = lavavu.cubehelix(100) if 'cmap' in kwargs: cmap = kwargs['cmap'] - # logger.info("Colouring section with %s min: %f, max: %f" % ( - # geological_feature.name, geological_feature.min(), geological_feature.max())) - # surf.colourmap(cmap, range=[geological_feature.min(), geological_feature.max()]) + def add_isosurface(self, geological_feature, value = None, isovalue=None, paint_with=None, slices=None, colour='red', nslices=None, cmap=None, filename=None, names=None, colours=None,**kwargs): diff --git a/dev/visualisation check.ipynb b/dev/visualisation check.ipynb new file mode 100644 index 000000000..e5f3cf24b --- /dev/null +++ b/dev/visualisation check.ipynb @@ -0,0 +1,6856 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "southern-plenty", + "metadata": {}, + "outputs": [], + "source": [ + "#import required \n", + "from LoopStructural import GeologicalModel\n", + "from LoopStructural.datasets import load_claudius\n", + "from LoopStructural.visualisation import LavaVuModelViewer\n", + "# from scipy.spatial.transform import Rotation as R\n", + "# from scipy.ndimage.interpolation import rotate\n", + "# import pyamg\n", + "# import pandas as pd\n", + "# import numpy as np\n", + "# import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "viral-sellers", + "metadata": {}, + "outputs": [], + "source": [ + "data, bb = load_claudius() # load data\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "competitive-advisory", + "metadata": {}, + "outputs": [], + "source": [ + "model = GeologicalModel(bb[0,:],bb[1,:],rescale=False)\n", + "model.set_model_data(data)\n", + "strati = model.create_and_add_foliation('strati',nelements=4e3,solver='pyamg',interpolatortype='FDI')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "recreational-borough", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + " \n", + "
\n", + "
\n", + "

Objects:

\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "view = LavaVuModelViewer(model)\n", + "view.add_section(model['strati'])\n", + "view.add_section(model['strati'],axis='y')\n", + "view.add_section(model['strati'],axis='z')\n", + "view.interactive()" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "processed-access", + "metadata": {}, + "outputs": [], + "source": [ + "from solver_diagnostics import solver_diagnostics" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "floral-kazakhstan", + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'interpolator'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mB\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstrati\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterpolator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuild_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'interpolator'" + ] + } + ], + "source": [ + "A,B = strati.interpolator.build_matrix()" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "hairy-compatibility", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Searching for optimal smoothed aggregation method for (1015000,1015000) matrix\n", + " ...\n", + " Detected a hermitian matrix\n", + " Detected positive definiteness\n", + " ...\n", + " Test 1 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None]\n", + " Test 2 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 3 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 4 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 5 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 6 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 7 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 8 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 9 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 10 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 11 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 12 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 13 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 14 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 15 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 16 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 17 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 18 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 19 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 20 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 21 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 22 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 23 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 24 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 25 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 26 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 27 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 28 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 29 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 30 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = V\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 31 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 32 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 33 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 34 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 35 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 36 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 37 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 38 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 39 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 40 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('symmetric', {'theta': 0.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 41 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 42 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 43 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 44 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 45 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 46 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 47 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 48 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 49 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 50 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 2.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 51 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 52 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = jacobi\n", + " improve_candidates = None\n", + " Test 53 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 54 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('jacobi', {'filter': True, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 55 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 56 out of 60\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 2, 'degree': 1, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 57 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 58 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 3, 'degree': 2, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " Test 59 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = [('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n", + " Test 60 out of 60\n", + " --> Failed this test\n", + " --> Solver descriptor is...\n", + " Solve phase arguments:\n", + " cycle = W\n", + " krylov accel = cg\n", + " tol = 1e-08\n", + " maxiter = 300\n", + " Setup phase arguments:\n", + " max_levels = 15\n", + " max_coarse = 300\n", + " coarse_solver = pinv\n", + " presmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " postsmoother = ('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1})\n", + " test\n", + " strength = ('evolution', {'k': 2, 'proj_type': 'l2', 'epsilon': 4.0})\n", + " aggregate = standard\n", + " smooth = ('energy', {'krylov': 'cg', 'maxiter': 4, 'degree': 3, 'weighting': 'local'})\n", + " improve_candidates = None\n", + " ...\n", + " --> Diagnostic Results located in solver_diagnostic.txt\n", + " ...\n", + " --> See automatically generated function definition\n", + " ./solver_diagnostic.py.\n", + "\n", + " Use the function defined here to generate and run the best\n", + " smoothed aggregation method found. The only argument taken\n", + " is a CSR/BSR matrix.\n", + "\n", + " To run: >>> # User must load/generate CSR/BSR matrix A\n", + " >>> from solver_diagnostic import solver_diagnostic\n", + " >>> solver_diagnostic(A)\n" + ] + } + ], + "source": [ + "solver_diagnostics(A,B_list=[(B,None,'test')])" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "domestic-leonard", + "metadata": {}, + "outputs": [], + "source": [ + "from pyamg import gallery\n", + "A = gallery.gauge_laplacian( 100)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "tamil-bishop", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "matrix([[ 4. +0.j , -0.95759664+0.28811225j,\n", + " 0. +0.j , ..., 0. +0.j ,\n", + " 0. +0.j , 0. +0.j ],\n", + " [-0.95759664-0.28811225j, 4. +0.j ,\n", + " -0.67245823+0.74013508j, ..., 0. +0.j ,\n", + " 0. +0.j , 0. +0.j ],\n", + " [ 0. +0.j , -0.67245823-0.74013508j,\n", + " 4. +0.j , ..., 0. +0.j ,\n", + " 0. +0.j , 0. +0.j ],\n", + " ...,\n", + " [ 0. +0.j , 0. +0.j ,\n", + " 0. +0.j , ..., 4. +0.j ,\n", + " -0.68431557+0.72918599j, 0. +0.j ],\n", + " [ 0. +0.j , 0. +0.j ,\n", + " 0. +0.j , ..., -0.68431557-0.72918599j,\n", + " 4. +0.j , -0.87569732-0.48286043j],\n", + " [ 0. +0.j , 0. +0.j ,\n", + " 0. +0.j , ..., 0. +0.j ,\n", + " -0.87569732+0.48286043j, 4. +0.j ]])" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A.todense()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "proud-baseball", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 20/20 [36:35<00:00, 109.80s/it]\n", + " 90%|█████████ | 18/20 [2:57:52<19:45, 592.92s/it] \n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;31m# nelements=1e4\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mstrati\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_and_add_foliation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'strati'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mnelements\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0msolver\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msolver\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0minterpolatortype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'FDI'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0mstrati\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuilder\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m \u001b[0mresults\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msolver\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'time'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mstart\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0mresults\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msolver\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'nx'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstrati\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterpolator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/modelling/features/geological_feature_builder.py\u001b[0m in \u001b[0;36mupdate\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 77\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 78\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuild\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuild_arguments\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 79\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mproperty\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 80\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/modelling/features/geological_feature_builder.py\u001b[0m in \u001b[0;36mbuild\u001b[0;34m(self, fold, fold_weights, data_region, **kwargs)\u001b[0m\n\u001b[1;32m 409\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'cgw'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0.0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 410\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterpolator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msetup_interpolator\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 411\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterpolator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msolve_system\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 412\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_up_to_date\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 413\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_feature\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/interpolators/geological_interpolator.py\u001b[0m in \u001b[0;36msolve_system\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 177\u001b[0m \u001b[0mSolves\u001b[0m \u001b[0mthe\u001b[0m \u001b[0minterpolation\u001b[0m \u001b[0mequations\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 178\u001b[0m \"\"\"\n\u001b[0;32m--> 179\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_solve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 180\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mup_to_date\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 181\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/interpolators/discrete_interpolator.py\u001b[0m in \u001b[0;36m_solve\u001b[0;34m(self, solver, **kwargs)\u001b[0m\n\u001b[1;32m 500\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msolver\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'cg'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 501\u001b[0m \u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minfo\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Solving using conjugate gradient\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 502\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mregion\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_solve_cg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mB\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 503\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msolver\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'chol'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 504\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mregion\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_solve_chol\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mB\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/python/LoopStructural/LoopStructural/interpolators/discrete_interpolator.py\u001b[0m in \u001b[0;36m_solve_cg\u001b[0;34m(self, A, B, precon, **kwargs)\u001b[0m\n\u001b[1;32m 446\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mprecon\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 447\u001b[0m \u001b[0mcgargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'M'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mprecon\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 448\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msla\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mB\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mcgargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnx\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 449\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 450\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_solve_pyamg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mB\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtol\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1e-8\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mx0\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/isolve/iterative.py\u001b[0m in \u001b[0;36mcg\u001b[0;34m(A, b, x0, tol, maxiter, M, callback, atol)\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/_lib/_threadsafety.py\u001b[0m in \u001b[0;36mcaller\u001b[0;34m(func, *a, **kw)\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcaller\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 43\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 44\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 45\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mscipy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_lib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecorator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecorate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcaller\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 46\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/isolve/iterative.py\u001b[0m in \u001b[0;36mcg\u001b[0;34m(A, b, x0, tol, maxiter, M, callback, atol)\u001b[0m\n\u001b[1;32m 327\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mijob\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 328\u001b[0m \u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m*=\u001b[0m \u001b[0msclr2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 329\u001b[0;31m \u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0msclr1\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mmatvec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 330\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mijob\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 331\u001b[0m \u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpsolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mwork\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mslice2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/interface.py\u001b[0m in \u001b[0;36mmatvec\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 230\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'dimension mismatch'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 231\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 232\u001b[0;31m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_matvec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 233\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 234\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatrix\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/interface.py\u001b[0m in \u001b[0;36m_matvec\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 197\u001b[0m \u001b[0mwill\u001b[0m \u001b[0mdefine\u001b[0m \u001b[0mmatrix\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mvector\u001b[0m \u001b[0mmultiplication\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mwell\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 198\u001b[0m \"\"\"\n\u001b[0;32m--> 199\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatmat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 200\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 201\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmatvec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/interface.py\u001b[0m in \u001b[0;36mmatmat\u001b[0;34m(self, X)\u001b[0m\n\u001b[1;32m 335\u001b[0m % (self.shape, X.shape))\n\u001b[1;32m 336\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 337\u001b[0;31m \u001b[0mY\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_matmat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 338\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 339\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mY\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatrix\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/linalg/interface.py\u001b[0m in \u001b[0;36m_matmat\u001b[0;34m(self, X)\u001b[0m\n\u001b[1;32m 729\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 730\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_matmat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 731\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 732\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 733\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_adjoint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/base.py\u001b[0m in \u001b[0;36mdot\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 357\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 358\u001b[0m \"\"\"\n\u001b[0;32m--> 359\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 360\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 361\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mpower\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/base.py\u001b[0m in \u001b[0;36m__mul__\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 467\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_mul_vector\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 468\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mN\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 469\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_mul_vector\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mravel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mM\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 470\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndim\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m2\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mN\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 471\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_mul_multivector\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/loopdev/lib/python3.9/site-packages/scipy/sparse/compressed.py\u001b[0m in \u001b[0;36m_mul_vector\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 474\u001b[0m \u001b[0;31m# csr_matvec or csc_matvec\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 475\u001b[0m \u001b[0mfn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_sparsetools\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_matvec'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 476\u001b[0;31m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mM\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mN\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindptr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindices\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 477\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 478\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "import time\n", + "from tqdm import tqdm\n", + "\n", + "results= {}\n", + "for solver in ['pyamg','cg','lsqr']:\n", + " results[solver] = {'nx':[],'nel':[],'time':[],'c':[]}\n", + " for nel in tqdm(np.arange(1e3,1e6,5e4)):\n", + " start = time.time()\n", + "# solver = 'pyamg'\n", + " # nelements=1e4\n", + " strati = model.create_and_add_foliation('strati',nelements=nel,solver=solver,interpolatortype='FDI')\n", + " strati.builder.update()\n", + " results[solver]['time'].append(time.time()-start)\n", + " results[solver]['nx'].append(strati.interpolator.nx)\n", + " results[solver]['nel'].append(nel)\n", + " np.save('scalar_field/{}_{}.npy'.format(solver,nel),strati.interpolator.c)\n", + "# results[solver]['c'].append(strati.interpolator.c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "circular-particle", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "faced-footage", + "metadata": {}, + "outputs": [], + "source": [ + "import pyamg\n", + "def solve(A,B):\n", + " print(tol)\n", + " return pyamg.solve(A, B, tol=tol, verb=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "severe-earthquake", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 0%| | 0/100 [00:00" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for solver in results.keys():\n", + " plt.scatter(results[solver]['nel'],(results[solver]['nx']),label=solver)\n", + "plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "square-steam", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, '$log_e(time)$')" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for solver in results.keys():\n", + " plt.scatter(results[solver]['nel'],np.log(results[solver]['time']),label=solver)\n", + "plt.legend()\n", + "plt.xlabel('Number of elements')\n", + "plt.ylabel(r'$log_e(time)$')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "auburn-reply", + "metadata": {}, + "outputs": [], + "source": [ + "for solver in results.keys():\n", + " plt.scatter(results[solver]['nel'],(results[solver]['time']),label=solver)\n", + "plt.legend()\n", + "plt.xlabel('Number of elements')\n", + "plt.ylabel(r'$log_e(time)$')" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "included-color", + "metadata": {}, + "outputs": [], + "source": [ + "result = []\n", + "# for nel in results['cg']['nel']:\n", + "results['cg']['nel'][10]\n", + "solver='cg'\n", + "cg = np.load('scalar_field/{}_{}.npy'.format(solver,nel))\n", + "solver='lsqr'\n", + "pyamg=np.load('scalar_field/{}_{}.npy'.format(solver,nel))\n", + "result.append(np.sum(np.abs(cg-pyamg)))\n", + "strati = model.create_and_add_foliation('strati',nelements=nel,solver='pyamg',interpolatortype='FDI')\n", + "strati.interpolator.c = cg\n", + "strati2 = model.create_and_add_foliation('strati',nelements=nel,solver='pyamg',interpolatortype='FDI')\n", + "strati2.interpolator.c = pyamg\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "realistic-space", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/lgrose/dev/python/LoopStructural/LoopStructural/visualisation/model_visualisation.py:305: FutureWarning: marching_cubes_lewiner is deprecated in favor of marching_cubes. marching_cubes_lewiner will be removed in version 0.19\n", + " verts, faces, normals, values = marching_cubes(\n", + "/home/lgrose/dev/python/LoopStructural/LoopStructural/visualisation/model_visualisation.py:305: FutureWarning: marching_cubes_lewiner is deprecated in favor of marching_cubes. marching_cubes_lewiner will be removed in version 0.19\n", + " verts, faces, normals, values = marching_cubes(\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + " \n", + "
\n", + "
\n", + "

Objects:

\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "slices = [0,60,250,320]\n", + "view = LavaVuModelViewer(model)\n", + "view.add_isosurface(strati,slices=slices,colour='blue')\n", + "view.add_isosurface(strati2,slices=slices)\n", + "view.interactive()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "nearby-better", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([4., 2., 2., 2., 3., 2., 2., 1., 0., 2.]),\n", + " array([0.0127047 , 0.45990958, 0.90711446, 1.35431934, 1.80152422,\n", + " 2.2487291 , 2.69593398, 3.14313886, 3.59034374, 4.03754862,\n", + " 4.4847535 ]),\n", + " )" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import time\n", + "from tqdm import tqdm\n", + "\n", + "results= {}\n", + "for solver in ['pyamg','cg','lsqr']:\n", + " results[solver] = {'nx':[],'nel':[],'time':[],'c':[]}\n", + " for nel in tqdm(np.arange(1e3,1e5,5e3)):\n", + " start = time.time()\n", + "# solver = 'pyamg'\n", + " # nelements=1e4\n", + " strati = model.create_and_add_foliation('strati',nelements=nel,solver=solver,interpolatortype='FDI')\n", + " strati.builder.update()\n", + " results[solver]['time'].append(time.time()-start)\n", + " results[solver]['nx'].append(strati.interpolator.nx)\n", + " results[solver]['nel'].append(nel)\n", + " np.save('scalar_field/{}_{}.npy'.format(solver,nel),strati.interpolator.c)\n", + "# results[solver]['c'].append(strati.interpolator.c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "classical-danish", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/user_guide/geological_model.rst b/docs/source/user_guide/geological_model.rst index 88c56fd97..0001d6006 100644 --- a/docs/source/user_guide/geological_model.rst +++ b/docs/source/user_guide/geological_model.rst @@ -10,6 +10,7 @@ Creating a model manually A GeologicalModel can be created using the default constructor. .. code-block:: + model = GeologicalModel(origin,maximum) Additional arguments that can be provided are: diff --git a/docs/source/user_guide/visualisation.rst b/docs/source/user_guide/visualisation.rst index 5dbbf9d4f..f1785d4ea 100644 --- a/docs/source/user_guide/visualisation.rst +++ b/docs/source/user_guide/visualisation.rst @@ -2,4 +2,135 @@ LavaVuModelViewer ================= LoopStructural uses the powerful lavaVu visualisaton library for visualising the 3D models as surfaces and scalar fields. LavaVu provides an interative viewer inside jupyter notebooks and can use matplotlib colourmaps as well as export the model to webgl. +The LavaVuModelViewer provides an easy to use interfaces for adding GeologicalFeatures to the viewer, the base lavaVu object can still be used. +Some of the functions in the viewer require a bounding box to be able to draw isosurfaces or scalar fields. +By default the viewer is initialised with a GeologicalModel and the origin and maximum of the model are used to set the viewers extents. +It is also possible to modify this manually by changing the bounding_box attribute. + +Visualising GeologicalFeatures +------------------------------ + +There are four main ways a GeologicalFeature can be visualised. +1. Scalar field showing the value of the implicit function on a block representing the model domain + +.. code-block:: + + view.add_scalar_field(geological_feature) + +2. Surfaces extracted from isovalues of the implicit function + +.. code-block:: + + view.add_isosurface(geological_feature,value=0) + +3. Vector field representing the gradient of the implicit function + +.. code-block:: + + view.add_isosurface(geological_feature) + +4. Cross section showing the value of the implicit function at a particular location inside the model + +.. code-block:: + + view.add_section(geological_feature,axis='x',value=0) + +When adding to the viewer there are a number of common arguments that can be specified to change the behaviour: + + .. list-table:: Viewer kwargs + :widths: 25 75 + :header-rows: 1 + + * - Parameter + - Options + * - name + - overwrite the name of the object to be added into the viewer + * - vmin + - minimum value for colourmap + * - vmax + - maximum value for colourmap + * - cmap + - matplotlib colourmap or string with name of matplotlib colourmap e.g. 'rainbow' + +The default behaviour of the viewer can also be modified. +To change the resolution of the scalar field or isosurfacing, either set the number of steps in x,y,z or the total number of elements. + +.. code-block:: + + view.nsteps = np.array([nx,ny,nz]) + print(view.nsteps) + view.nelements = 1e6 + print(view.nsteps) + + + +Visualising data +---------------- + +The input data for the geological model can also be visualised within the viewer. +To add all of the data attached to a GeologicalFeature + +.. code-block:: + + view.add_data(geological_feature,grad=True,value=True,tang=True,interface=True) + +Alternatively, points can be added into the model using the: + +.. code-block:: + + view.add_points(xyz,name='name of viewer object') + +or points with an associated value: + +.. code-block:: + view.add_value_data(xyz,val,name='name of viewer object') + +or points with an associated vector: + +.. code-block:: + + view.add_vector_data(xyz,vec,name='name of viewer object') + +**Warning, you cannot have two objects in the viewer with the same name** + +Visualising geological model +---------------------------- + +Where the GeologicalModel has an assocaited stratigraphic column including a list of faults in the model, this can be used for automatically visualising the model. +To add a block model showing the stratigraphic unit distribution, where the value is linked to the *id* in the stratigraphic column. + +.. code-block:: + + view.add_model() + +alternatively, the surfaces can be added to the visualisation. + +.. code-block:: + + view.add_model_surfaces(faults=True) + +Where the faults flag allows you to disable visualising the fault surface. +This function will add a surface for every stratigraphic unit in the stratigraphic column. + +Custom visualisation +-------------------- + +It is also possible to pass custom functions to the viewer using the LambdaGeologicalFeature. +The LambdaGeologicalFeature is a class allowing for a function describing the value at locations or vector field. + +.. code-block:: + + from LoopStructural.modelling.features import LambdaGeologicalFeature + def x_function(xyz): + return xyz[:,0] + custom_feature = LambdaGeologicalFeature(x_function,name='x feature') + view.add_isosurface(custom_feature,value) + view.add_scalar_field(custom_feature) + +The function passed to the LambdaGeologicalFeature can be as simple or complicated as required. +It will be evaluated for the locations within the model that the visualisation requires, usually between the origin and maximum of the geoloical model. +By default the min and max values are 0, however these can be overwritten by setting the attribute min and max to the required values. + + + From 5ae2f4669b9b62a2984ddb9c71f6127e3d2c6e1f Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Tue, 9 Feb 2021 11:28:49 +1100 Subject: [PATCH 27/29] (BUG) updating for flake8 --- .../modelling/core/geological_model.py | 3 +-- .../modelling/fault/fault_builder.py | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/LoopStructural/modelling/core/geological_model.py b/LoopStructural/modelling/core/geological_model.py index 9949149ad..23e10b102 100644 --- a/LoopStructural/modelling/core/geological_model.py +++ b/LoopStructural/modelling/core/geological_model.py @@ -532,8 +532,7 @@ def get_interpolator(self, interpolatortype='PLI', nelements=1e5, logger.info("Creating regular tetrahedron mesh with %i elements \n" "for modelling using DFI" % mesh.ntetra) return DFI(mesh, kwargs['fold']) - if interpolatortype == 'Surfe' or interpolatortype == 'surfe' and \ - surfe: + if interpolatortype == 'Surfe' or interpolatortype == 'surfe': # move import of surfe to where we actually try and use it try: from LoopStructural.interpolators.surfe_wrapper import \ diff --git a/LoopStructural/modelling/fault/fault_builder.py b/LoopStructural/modelling/fault/fault_builder.py index a8cef99a2..079d09076 100644 --- a/LoopStructural/modelling/fault/fault_builder.py +++ b/LoopStructural/modelling/fault/fault_builder.py @@ -110,17 +110,18 @@ def set_mesh_geometry(self,buffer): self.builders[0].set_interpolation_geometry(self.origin-length*buffer,self.maximum+length*buffer) def add_splay(self,splayregion,splay): - for i in range(3): - # work out the values of the nodes where we want hard - # constraints - idc = np.arange(0, interpolator.support.n_nodes)[ - kwargs['splayregion'](interpolator.support.nodes)] - val = kwargs['splay'][i].evaluate_value( - interpolator.support.nodes[ - kwargs['splayregion'](interpolator.support.nodes), :]) - mask = ~np.isnan(val) - fault_frame_builder[i].interpolator.add_equality_constraints( - idc[mask], val[mask]) + # for i in range(3): + # # work out the values of the nodes where we want hard + # # constraints + # idc = np.arange(0, interpolator.support.n_nodes)[ + # kwargs['splayregion'](interpolator.support.nodes)] + # val = kwargs['splay'][i].evaluate_value( + # interpolator.support.nodes[ + # kwargs['splayregion'](interpolator.support.nodes), :]) + # mask = ~np.isnan(val) + # fault_frame_builder[i].interpolator.add_equality_constraints( + # idc[mask], val[mask]) + pass def update(self): for i in range(3): self.builders[i].update() \ No newline at end of file From 106f583d3bbf94e6be31578c7b538005659ad41e Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Tue, 9 Feb 2021 11:31:53 +1100 Subject: [PATCH 28/29] updating test --- test.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/test.sh b/test.sh index 481f315ea..1694c7dd9 100755 --- a/test.sh +++ b/test.sh @@ -1,5 +1,3 @@ -eval "$(conda shell.bash hook)" -conda activate loop2 flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics pytest From d740b2bd91dbb758f30a4c1824fd8ff448c0bf08 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Tue, 9 Feb 2021 12:58:11 +1100 Subject: [PATCH 29/29] Update change_list.md --- change_list.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/change_list.md b/change_list.md index a8457927f..f2717b0ef 100644 --- a/change_list.md +++ b/change_list.md @@ -1,6 +1,7 @@ # Major changes +- Faults can be defined by the influence distance, extent and vertical radius +- Scalar fields are interpolated when required, not when added +- To interpolate all scalar fields run model.update() # Minor changes -* Added getitem accessor for returning feature from model -* Model is set for structural frames -* Adding tests for grids/tetras \ No newline at end of file +- various small changes to visualisation \ No newline at end of file