From 2af2b09cee80dc2568148170fddfbf12e37bdf78 Mon Sep 17 00:00:00 2001 From: Chris Vogl Date: Fri, 6 Jul 2018 18:50:39 -0700 Subject: [PATCH 1/6] Added abldata to data.py and made necessary ABL modifications to clawdata object --- src/python/clawutil/data.py | 183 +++++++++++++++++++++++++++--------- 1 file changed, 140 insertions(+), 43 deletions(-) diff --git a/src/python/clawutil/data.py b/src/python/clawutil/data.py index 248d239..1b8372f 100644 --- a/src/python/clawutil/data.py +++ b/src/python/clawutil/data.py @@ -46,15 +46,15 @@ def strip_archive_extensions(path, extensions=["tar", "tgz", "bz2", "gz"]): return path -def get_remote_file(url, output_dir=None, file_name=None, force=False, +def get_remote_file(url, output_dir=None, file_name=None, force=False, verbose=False, ask_user=False, unpack=True): r"""Fetch file located at *url* and store at *output_dir*. :Input: - + - *url* (path) - URL to file to be downloaded. - *output_dir* (path) - Directory that the remote file will be downloaded - to. Defaults to the GeoClaw sratch directory defined by + to. Defaults to the GeoClaw sratch directory defined by *os.path.join(os.environ['CLAW'], 'geoclaw', 'scratch')*. - *file_name* (string) - Name of local file. This defaults to the name of the remote file. @@ -65,7 +65,7 @@ def get_remote_file(url, output_dir=None, file_name=None, force=False, file before proceeding. Default is *False* :Raises: - + Exceptions are raised from the *urllib* module having to do with errors fetching the remote file. Please see its documentation for more details of the exceptions that can be raised. @@ -78,7 +78,7 @@ def get_remote_file(url, output_dir=None, file_name=None, force=False, if file_name is None: file_name = os.path.basename(url) - + output_path = os.path.join(output_dir, file_name) unarchived_output_path = strip_archive_extensions(output_path) @@ -92,7 +92,7 @@ def get_remote_file(url, output_dir=None, file_name=None, force=False, if verbose: print("*** Aborting download.") return None - + if not os.path.exists(output_path): # Fetch remote file, will raise a variety of exceptions depending on # the retrieval problem if it happens @@ -108,7 +108,7 @@ def get_remote_file(url, output_dir=None, file_name=None, force=False, if tarfile.is_tarfile(output_path) and unpack: if verbose: - print("Un-archiving %s to %s..." % (output_path, + print("Un-archiving %s to %s..." % (output_path, unarchived_output_path)) with tarfile.open(output_path, mode="r:*") as tar_file: tar_file.extractall(path=output_dir) @@ -139,14 +139,14 @@ class ClawData(object): but new attributes can only be added using the method add_attribute. Trying to set a nonexistent attribute will raise an AttributeError - exception, except for those starting with '_'. + exception, except for those starting with '_'. """ def __init__(self, attributes=None): - - # Attribute to store a list of the allowed attributes, - # appended to when add_attribute is used: + + # Attribute to store a list of the allowed attributes, + # appended to when add_attribute is used: object.__setattr__(self,'_attributes',[]) # Output file handle @@ -170,7 +170,7 @@ def __setattr__(self,name,value): print("*** Perhaps a typo?") print("*** Add new attributes using add_attribute method") raise AttributeError("Unrecognized attribute: %s" % name) - + # attribute exists, ok to set: object.__setattr__(self,name,value) @@ -238,7 +238,7 @@ def has_attribute(self,name): """ return name in self._attributes - + def iteritems(self): r""" Returns an iterator of attributes and values from this object @@ -334,12 +334,12 @@ def data_write(self, name=None, value=None, alt_name=None, description=''): padded_value = string_value.ljust(20) padded_name = alt_name.ljust(20) if description != '': - self._out_file.write('%s =: %s # %s \n' % + self._out_file.write('%s =: %s # %s \n' % (padded_value, padded_name, description)) else: - self._out_file.write('%s =: %s\n' % + self._out_file.write('%s =: %s\n' % (padded_value, padded_name)) - + def read(self,path,force=False): r"""Read and fill applicable data attributes. @@ -365,7 +365,7 @@ def read(self,path,force=False): self.add_attribute(varname,value) else: setattr(self,varname,value) - + def _parse_value(self,value): r""" @@ -495,7 +495,7 @@ def new_UserData(self,name,fname): def write(self): r"""Write out each data objects in datalist """ - + import clawpack.amrclaw.data as amrclaw for data_object in self.data_list: @@ -516,6 +516,10 @@ class ClawInputData(ClawData): def __init__(self, num_dim): super(ClawInputData,self).__init__() + # Add absorbing boundary layer data object + abldata = ClawABLData(num_dim) + self.add_attribute('abldata',abldata) + # Set default values: self.add_attribute('num_dim',num_dim) self.add_attribute('num_eqn',1) @@ -532,7 +536,7 @@ def __init__(self, num_dim): self.add_attribute('output_q_components','all') self.add_attribute('output_aux_components','none') self.add_attribute('output_aux_onlyonce',True) - + self.add_attribute('dt_initial',1.e-5) self.add_attribute('dt_max',1.e99) self.add_attribute('dt_variable',True) @@ -549,7 +553,7 @@ def __init__(self, num_dim): self.add_attribute('t0',0.) self.add_attribute('num_ghost',2) self.add_attribute('use_fwaves',False) - + if num_dim == 1: self.add_attribute('lower',[0.]) self.add_attribute('upper',[1.]) @@ -557,6 +561,7 @@ def __init__(self, num_dim): self.add_attribute('bc_lower',[0]) self.add_attribute('bc_upper',[0]) self.add_attribute('transverse_waves',0) + self.add_attribute('abl_depth_lower',[0.]) elif num_dim == 2: self.add_attribute('lower',[0.,0.]) self.add_attribute('upper',[1.,1.]) @@ -588,13 +593,34 @@ def write(self, out_file='claw.data', data_source='setrun.py'): self.open_data_file(out_file,data_source) self.data_write('num_dim') - self.data_write('lower') - self.data_write('upper') - self.data_write('num_cells') + + # If necessary, adjust data for absorbing boundary layer + num_aux = self.num_aux + if self.abldata.abltype == 0: + self.data_write('lower') + self.data_write('upper') + self.data_write('num_cells') + else: + upper = np.array(self.upper) + lower = np.array(self.lower) + num_cells = np.array(self.num_cells) + depth_lower = np.array(self.abldata.depth_lower) + depth_upper = np.array(self.abldata.depth_upper) + dx = (upper-lower)/num_cells + num_cells_abl_lower = np.ceil(depth_lower/dx) + num_cells_abl_upper = np.ceil(depth_upper/dx) + num_cells += int(num_cells_abl_lower) + int(num_cells_abl_upper) + lower -= num_cells_abl_lower*dx + upper += num_cells_abl_upper*dx + self.data_write('', value=lower, alt_name='lower') + self.data_write('', value=upper, alt_name='upper') + self.data_write('', value=num_cells, alt_name='num_cells') + num_aux += 1 + self.data_write() # writes blank line self.data_write('num_eqn') self.data_write('num_waves') - self.data_write('num_aux') + self.data_write('', value=num_aux, alt_name='num_aux') self.data_write() # writes blank line self.data_write('t0') @@ -630,7 +656,7 @@ def write(self, out_file='claw.data', data_source='setrun.py'): else: raise ValueError("*** Error in data parameter: " + \ "output_format unrecognized: ",self.output_format) - + self.data_write('output_format') if self.output_q_components == 'all': @@ -642,24 +668,24 @@ def write(self, out_file='claw.data', data_source='setrun.py'): print("*** WARNING: Selective output_q_components not implemented") print("*** Will output all components of q") iout_q = self.num_eqn * [1] - + # Write out local value of iout_q rather than a data member self.data_write('', value=iout_q, alt_name='iout_q') - if self.num_aux > 0: + if num_aux > 0: if isinstance(self.output_aux_components,six.string_types): if self.output_aux_components.lower() == 'all': - iout_aux = self.num_aux * [1] + iout_aux = num_aux * [1] elif self.output_aux_components.lower() == 'none': - iout_aux = self.num_aux * [0] + iout_aux = num_aux * [0] else: raise ValueError("Invalid aux array component option.") else: iout_aux = np.where(self.output_aux_components, 1, 0) print("*** WARNING: Selective output_aux_components not implemented") print("*** Will output all components of aux") - iout_aux = self.num_aux * [1] + iout_aux = num_aux * [1] self.data_write(name='', value=iout_aux, alt_name='iout_aux') self.data_write('output_aux_onlyonce') @@ -679,32 +705,32 @@ def write(self, out_file='claw.data', data_source='setrun.py'): else: # Transverse options different in 2D and 3D if self.num_dim == 2: - if self.transverse_waves in [0,'none']: + if self.transverse_waves in [0,'none']: self.transverse_waves = 0 - elif self.transverse_waves in [1,'increment']: + elif self.transverse_waves in [1,'increment']: self.transverse_waves = 1 - elif self.transverse_waves in [2,'all']: + elif self.transverse_waves in [2,'all']: self.transverse_waves = 2 else: raise AttributeError("Unrecognized transverse_waves: %s" \ % self.transverse_waves) else: # 3D - if self.transverse_waves in [0,'none']: + if self.transverse_waves in [0,'none']: self.transverse_waves = 0 - elif self.transverse_waves in [1,'increment']: + elif self.transverse_waves in [1,'increment']: self.transverse_waves = 11 - elif self.transverse_waves in [2,'all']: + elif self.transverse_waves in [2,'all']: self.transverse_waves = 22 if not (self.transverse_waves in [0, 10, 11, 20, 21, 22]): raise AttributeError("Unrecognized transverse_waves: %s" \ % self.transverse_waves) self.data_write(None, self.transverse_waves, 'transverse_waves') - if self.dimensional_split in [0,'unsplit']: + if self.dimensional_split in [0,'unsplit']: self.dimensional_split = 0 - elif self.dimensional_split in [1,'godunov']: + elif self.dimensional_split in [1,'godunov']: self.dimensional_split = 1 - elif self.dimensional_split in [2,'strang']: + elif self.dimensional_split in [2,'strang']: if self.num_dim == 3: raise AttributeError("Strang dimensional splitting not supported in 3D") else: @@ -713,14 +739,14 @@ def write(self, out_file='claw.data', data_source='setrun.py'): raise AttributeError("Unrecognized dimensional_split: %s" \ % self.dimensional_split) self.data_write('dimensional_split') - + self.data_write('verbosity') - if self.source_split in [0,'none']: + if self.source_split in [0,'none']: self.source_split = 0 - elif self.source_split in [1,'godunov']: + elif self.source_split in [1,'godunov']: self.source_split = 1 - elif self.source_split in [2,'strang']: + elif self.source_split in [2,'strang']: self.source_split = 2 else: raise AttributeError("Unrecognized source_split: %s" \ @@ -793,6 +819,77 @@ def write(self, out_file='claw.data', data_source='setrun.py'): self.data_write() self.close_data_file() + self.abldata.write() + +class ClawABLData(ClawData): + r""" + Object containing absorbing boundary layer input data, usually written to 'abl.data'. + + + """ + + def __init__(self, num_dim): + super(ClawABLData,self).__init__() + + # Set default values: + self.add_attribute('abltype',0) + self.add_attribute('parameters',{}) + + if num_dim == 1: + self.add_attribute('depth_lower',[0.]) + self.add_attribute('depth_upper',[0.]) + elif num_dim == 2: + self.add_attribute('depth_lower',[0.,0.]) + self.add_attribute('depth_upper',[0.,0.]) + elif num_dim == 3: + self.add_attribute('depth_lower',[0.,0.,0.]) + self.add_attribute('depth_upper',[0.,0.,0.]) + else: + raise ValueError("Only num_dim=1, 2, or 3 supported ") + + + + def write(self, out_file='abl.data', data_source='setrun.py'): + r"""Write input data to a file""" + self.open_data_file(out_file,data_source) + + if self.abltype == 'trigonometric': + self.data_write('', value=1, alt_name='abltype') + + elif self.abltype == 'appelo_colonius': + self.data_write('', value=2, alt_name='abltype') + if 'epsilon' in self.parameters.keys(): + self.data_write('', value=self.parameters['epsilon'], alt_name='epsilon') + else: + raise ValueError("Use of Appello/Colonius ABL requires value for epsilon.") + if 'p' in self.parameters.keys(): + self.data_write('', value=self.parameters['p'], alt_name='p') + else: + raise ValueError("Use of Appello/Colonius ABL requires value for p.") + if 'q' in self.parameters.keys(): + self.data_write('', value=self.parameters['q'], alt_name='q') + else: + raise ValueError("Use of Appello/Colonius ABL requires value for q.") + + elif self.abltype == 'petersson_sjogreen': + self.data_write('', value=3, alt_name='abltype') + if 'epsilon' in self.parameters.keys(): + self.data_write('', value=self.parameters['epsilon'], alt_name='epsilon') + else: + raise ValueError("Use of Petersson/Sjogreen ABL requires value for epsilon.") + + else: + self.data_write('abltype') + for key in self.parameters.keys(): + self.data_write('', value=self.parameters[key], alt_name=key) + + self.data_write('depth_lower') + self.data_write('depth_upper') + + self.data_write() + self.close_data_file() + + class UserData(ClawData): r""" From 328204452192b47309bd84e2b2e7953620a5439a Mon Sep 17 00:00:00 2001 From: Chris Vogl Date: Fri, 6 Jul 2018 19:43:43 -0700 Subject: [PATCH 2/6] Generalized some of the data.py modifications to N dimensions --- src/python/clawutil/data.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/python/clawutil/data.py b/src/python/clawutil/data.py index 1b8372f..8240b9c 100644 --- a/src/python/clawutil/data.py +++ b/src/python/clawutil/data.py @@ -609,13 +609,14 @@ def write(self, out_file='claw.data', data_source='setrun.py'): dx = (upper-lower)/num_cells num_cells_abl_lower = np.ceil(depth_lower/dx) num_cells_abl_upper = np.ceil(depth_upper/dx) - num_cells += int(num_cells_abl_lower) + int(num_cells_abl_upper) + for j in range(self.num_dim): + num_cells[j] += int(num_cells_abl_lower[j]) + int(num_cells_abl_upper[j]) lower -= num_cells_abl_lower*dx upper += num_cells_abl_upper*dx self.data_write('', value=lower, alt_name='lower') self.data_write('', value=upper, alt_name='upper') self.data_write('', value=num_cells, alt_name='num_cells') - num_aux += 1 + num_aux += self.num_dim self.data_write() # writes blank line self.data_write('num_eqn') From 378484e473353ff808de9e8f634c18ae1e600000 Mon Sep 17 00:00:00 2001 From: Chris Vogl Date: Mon, 9 Jul 2018 10:48:35 -0700 Subject: [PATCH 3/6] removed unused abl item in data.py --- src/python/clawutil/data.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python/clawutil/data.py b/src/python/clawutil/data.py index 8240b9c..96ab1b7 100644 --- a/src/python/clawutil/data.py +++ b/src/python/clawutil/data.py @@ -561,7 +561,6 @@ def __init__(self, num_dim): self.add_attribute('bc_lower',[0]) self.add_attribute('bc_upper',[0]) self.add_attribute('transverse_waves',0) - self.add_attribute('abl_depth_lower',[0.]) elif num_dim == 2: self.add_attribute('lower',[0.,0.]) self.add_attribute('upper',[1.,1.]) From 4f195749bc04388aa82115326b87e54bf7efd4c1 Mon Sep 17 00:00:00 2001 From: Chris Vogl Date: Sun, 29 Jul 2018 14:47:55 -0700 Subject: [PATCH 4/6] Needed to update data.py to call gauge's write function to account for ABL --- src/python/clawutil/data.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/python/clawutil/data.py b/src/python/clawutil/data.py index 96ab1b7..4b3ef2d 100644 --- a/src/python/clawutil/data.py +++ b/src/python/clawutil/data.py @@ -500,7 +500,10 @@ def write(self): for data_object in self.data_list: if isinstance(data_object, amrclaw.GaugeData): - data_object.write(self.clawdata.num_eqn, self.clawdata.num_aux) + if self.clawdata.abldata.abltype == 0: + data_object.write(self.clawdata.num_eqn, self.clawdata.num_aux) + else: + data_object.write(self.clawdata.num_eqn, self.clawdata.num_aux+self.clawdata.num_dim) else: data_object.write() From 9d4792a1e88692b980e4034eb6e21338362a89e6 Mon Sep 17 00:00:00 2001 From: Chris Vogl Date: Thu, 14 Feb 2019 10:49:36 -0800 Subject: [PATCH 5/6] updates for use of both g(z) and g'(z) --- src/python/clawutil/data.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/clawutil/data.py b/src/python/clawutil/data.py index 34cc6e4..0ab5423 100644 --- a/src/python/clawutil/data.py +++ b/src/python/clawutil/data.py @@ -525,7 +525,7 @@ def write(self): if self.clawdata.abldata.abltype == 0: data_object.write(self.clawdata.num_eqn, self.clawdata.num_aux) else: - data_object.write(self.clawdata.num_eqn, self.clawdata.num_aux+self.clawdata.num_dim) + data_object.write(self.clawdata.num_eqn, self.clawdata.num_aux+2*self.clawdata.num_dim) else: data_object.write() @@ -640,7 +640,7 @@ def write(self, out_file='claw.data', data_source='setrun.py'): self.data_write('', value=lower, alt_name='lower') self.data_write('', value=upper, alt_name='upper') self.data_write('', value=num_cells, alt_name='num_cells') - num_aux += self.num_dim + num_aux += 2*self.num_dim self.data_write() # writes blank line self.data_write('num_eqn') From b6fa748cb8f346dd3282f9667dec226b58e35343 Mon Sep 17 00:00:00 2001 From: Chris Vogl Date: Thu, 14 Feb 2019 23:31:14 -0800 Subject: [PATCH 6/6] removed aux_num increase if abl is specified --- src/python/clawutil/data.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/python/clawutil/data.py b/src/python/clawutil/data.py index 0ab5423..2dce06d 100644 --- a/src/python/clawutil/data.py +++ b/src/python/clawutil/data.py @@ -522,10 +522,7 @@ def write(self): for data_object in self.data_list: if isinstance(data_object, amrclaw.GaugeData): - if self.clawdata.abldata.abltype == 0: - data_object.write(self.clawdata.num_eqn, self.clawdata.num_aux) - else: - data_object.write(self.clawdata.num_eqn, self.clawdata.num_aux+2*self.clawdata.num_dim) + data_object.write(self.clawdata.num_eqn, self.clawdata.num_aux) else: data_object.write() @@ -640,7 +637,6 @@ def write(self, out_file='claw.data', data_source='setrun.py'): self.data_write('', value=lower, alt_name='lower') self.data_write('', value=upper, alt_name='upper') self.data_write('', value=num_cells, alt_name='num_cells') - num_aux += 2*self.num_dim self.data_write() # writes blank line self.data_write('num_eqn')