Source code for hyvr.geo.stratum

import numpy as np
import hyvr.optimized as ho
import hyvr.utils as hu
from hyvr.geo.contact_surface import ContactSurface

[docs]def prob_choose(types, probs): # TODO: At the moment the given probabilities are only relative return np.random.choice(types, p=np.asarray(probs)/np.sum(probs))
[docs]class Stratum: def __init__(self, bottom_surface, top_surface, params, ae_types, grid): """ Stratum constructor. This generates the stratum by generating the AEs within. Parameters ---------- bottom_surface : ContactSurface object The bottom surface of the stratum top_surface : ContactSurface object The top surface of the stratum params : dict Dictionary with other necessary parameters ae_types : list of AEType objects The possible AE types within this stratum grid : Grid object """ self.bottom_surface = bottom_surface self.top_surface = top_surface self.params = params self.name = params['strata'] self.ae_types = ae_types self.ae_type_names = [ae_type.name for ae_type in ae_types] self.bg_facies = params['bg_facies'] self.bg_azim = params['bg_azim'] self.bg_dip = params['bg_dip'] # generate AEs self.zmin = self.bottom_surface.zmin self.zmax = self.top_surface.zmax self.ae_zmins = [] self.ae_zmaxs = [] self.aes = [] # first top is top of stratum ae_top_surface = self.top_surface # choose type of first AE curr_ae_type = prob_choose(self.ae_types, self.params['ae_prob']) znow = self.top_surface.zmean while znow > self.bottom_surface.zmean: num_type = self.ae_type_names.index(curr_ae_type.name) hu.print_to_stdout('Generating', curr_ae_type.name, 'from {:2.3f} m'.format(znow)) # find height of AE mean_height = self.params['ae_z_mean'][num_type] # TODO: It might be nice to specify the height variance in the inifile height = np.random.normal(mean_height, mean_height*0.1) # potential avulsion if np.random.uniform() <= self.params['avul_prob'][0]: dz = -np.random.uniform(*self.params['avul']) else: dz = 0 znow -= height + dz # create bottom contact surface # ----------------------------- # the type of the bottom surface is determined by the type of the # AE below, if it is not the lowest AE next_ae_type = prob_choose(self.ae_types, self.params['ae_prob']) if znow <= self.bottom_surface.zmean: # limit top surface of uppermost AE to top surface of stratum znow = self.bottom_surface.zmean ae_bottom_surface = self.bottom_surface else: bottom_surface_params = next_ae_type.params['contact_model'] bottom_surface_params['z'] = znow ae_bottom_surface = ContactSurface(grid, **bottom_surface_params) # if the bottom surface is above the top surface, we will assign # the (lower) top surface values instead ae_bottom_surface.use_lower_surface_value(ae_top_surface) # close to the bottom it might also be possible that the ae_bottom # is below the stratum bottom if the stratum bottom is not flat # in this case we will assign the (higher) bottom surface value instead ae_bottom_surface.use_higher_surface_value(self.bottom_surface) # generate element: this will place all the objects within an AE element = curr_ae_type.generate_realization(ae_bottom_surface, ae_top_surface, self, grid) self.aes.append(element) # if the minimum/maximum depth changed, update it ae_zmin = element.zmin if ae_zmin < self.zmin: self.zmin = ae_zmin self.ae_zmins.append(ae_zmin) ae_zmax = element.zmax if ae_zmax > self.zmax: self.zmax = ae_zmax self.ae_zmaxs.append(ae_zmax) # current bottom is top of next, next ae is new current ae ae_top_surface = ae_bottom_surface curr_ae_type = next_ae_type self.n_ae = len(self.aes) # convert lists to arrays self.ae_zmaxs = np.array(self.ae_zmaxs) self.ae_zmins = np.array(self.ae_zmins)