Source code for issm.autodiff

import numpy as np
from issm.dependent import dependent
from issm.independent import independent
from issm.fielddisplay import fielddisplay
from issm.checkfield import checkfield
from issm.WriteData import WriteData
from issm.MatlabFuncs import *

[docs]class autodiff(object): """ AUTODIFF class definition Usage: autodiff=autodiff(); """ def __init__(self,*args): # {{{ self.isautodiff = False self.dependents = [] self.independents = [] self.driver = 'fos_forward' self.obufsize = float('NaN') self.lbufsize = float('NaN') self.cbufsize = float('NaN') self.tbufsize = float('NaN') self.gcTriggerMaxSize = float('NaN') self.gcTriggerRatio = float('NaN') if not len(args): self.setdefaultparameters() else: raise RuntimeError("constructor not supported") # }}} def __repr__(self): # {{{ s =" automatic differentiation parameters:\n" s+="%s\n" % fielddisplay(self,'isautodiff',"indicates if the automatic differentiation is activated") s+="%s\n" % fielddisplay(self,'dependents',"list of dependent variables") s+="%s\n" % fielddisplay(self,'independents',"list of independent variables") s+="%s\n" % fielddisplay(self,'driver',"ADOLC driver ('fos_forward' or 'fov_forward')") s+="%s\n" % fielddisplay(self,'obufsize',"Number of operations per buffer (==OBUFSIZE in usrparms.h)") s+="%s\n" % fielddisplay(self,'lbufsize',"Number of locations per buffer (==LBUFSIZE in usrparms.h)") s+="%s\n" % fielddisplay(self,'cbufsize',"Number of values per buffer (==CBUFSIZE in usrparms.h)") s+="%s\n" % fielddisplay(self,'tbufsize',"Number of taylors per buffer (<=TBUFSIZE in usrparms.h)") s+="%s\n" % fielddisplay(self,'gcTriggerRatio',"free location block sorting/consolidation triggered if the ratio between allocated and used locations exceeds gcTriggerRatio") s+="%s\n" % fielddisplay(self,'gcTriggerMaxSize',"free location block sorting/consolidation triggered if the allocated locations exceed gcTriggerMaxSize)") return s # }}}
[docs] def setdefaultparameters(self): # {{{ self.obufsize = 524288 self.lbufsize = 524288 self.cbufsize = 524288 self.tbufsize = 524288 self.gcTriggerRatio=2.0 self.gcTriggerMaxSize=65536 return self
# }}}
[docs] def checkconsistency(self,md,solution,analyses): # {{{ #Early return if not self.isautodiff: return md md = checkfield(md,'fieldname','autodiff.obufsize','>=',524288) md = checkfield(md,'fieldname','autodiff.lbufsize','>=',524288) md = checkfield(md,'fieldname','autodiff.cbufsize','>=',524288) md = checkfield(md,'fieldname','autodiff.tbufsize','>=',524288) md = checkfield(md,'fieldname','autodiff.gcTriggerRatio','>=',2.0) md = checkfield(md,'fieldname','autodiff.gcTriggerMaxSize','>=',65536) #Driver value: md = checkfield(md,'fieldname','autodiff.driver','values',['fos_forward','fov_forward','fov_forward_all','fos_reverse','fov_reverse','fov_reverse_all']) #go through our dependents and independents and check consistency: for dep in self.dependents: dep.checkconsistency(md,solution,analyses) for i,indep in enumerate(self.independents): indep.checkconsistency(md,i,solution,analyses,self.driver) return md
# }}}
[docs] def marshall(self,prefix,md,fid): # {{{ WriteData(fid,prefix,'object',self,'fieldname','isautodiff','format','Boolean') WriteData(fid,prefix,'object',self,'fieldname','driver','format','String') #early return if not self.isautodiff: WriteData(fid,prefix,'data',False,'name','md.autodiff.mass_flux_segments_present','format','Boolean') WriteData(fid,prefix,'data',False,'name','md.autodiff.keep','format','Boolean') return #buffer sizes {{{ WriteData(fid,prefix,'object',self,'fieldname','obufsize','format','Double'); WriteData(fid,prefix,'object',self,'fieldname','lbufsize','format','Double'); WriteData(fid,prefix,'object',self,'fieldname','cbufsize','format','Double'); WriteData(fid,prefix,'object',self,'fieldname','tbufsize','format','Double'); WriteData(fid,prefix,'object',self,'fieldname','gcTriggerRatio','format','Double'); WriteData(fid,prefix,'object',self,'fieldname','gcTriggerMaxSize','format','Double'); #}}} #process dependent variables {{{ num_dependent_objects=len(self.dependents) WriteData(fid,prefix,'data',num_dependent_objects,'name','md.autodiff.num_dependent_objects','format','Integer') if num_dependent_objects: names=[] types=np.zeros(num_dependent_objects) indices=np.zeros(num_dependent_objects) for i,dep in enumerate(self.dependents): names.append(dep.name) types[i]=dep.typetoscalar() indices[i]=dep.index WriteData(fid,prefix,'data',names,'name','md.autodiff.dependent_object_names','format','StringArray') WriteData(fid,prefix,'data',types,'name','md.autodiff.dependent_object_types','format','IntMat','mattype',3) WriteData(fid,prefix,'data',indices,'name','md.autodiff.dependent_object_indices','format','IntMat','mattype',3) #}}} #process independent variables {{{ num_independent_objects=len(self.independents) WriteData(fid,prefix,'data',num_independent_objects,'name','md.autodiff.num_independent_objects','format','Integer') if num_independent_objects: names=[None] * num_independent_objects types=np.zeros(num_independent_objects) for i,indep in enumerate(self.independents): names[i]=indep.name types[i]=indep.typetoscalar() WriteData(fid,prefix,'data',names,'name','md.autodiff.independent_object_names','format','StringArray') WriteData(fid,prefix,'data',types,'name','md.autodiff.independent_object_types','format','IntMat','mattype',3) #}}} #if driver is fos_forward, build index: {{{ if strcmpi(self.driver,'fos_forward'): index=0 for indep in self.independents: if not np.isnan(indep.fos_forward_index): index+=indep.fos_forward_index break else: if strcmpi(indep.type,'scalar'): index+=1 else: index+=indep.nods index-=1 #get c-index numbering going WriteData(fid,prefix,'data',index,'name','md.autodiff.fos_forward_index','format','Integer') #}}} #if driver is fos_reverse, build index: {{{ if strcmpi(self.driver,'fos_reverse'): index=0 for dep in self.dependents: if not np.isnan(dep.fos_reverse_index): index+=dep.fos_reverse_index break else: if strcmpi(dep.type,'scalar'): index+=1 else: index+=dep.nods index-=1 #get c-index numbering going WriteData(fid,prefix,'data',index,'name','md.autodiff.fos_reverse_index','format','Integer') #}}} #if driver is fov_forward, build indices: {{{ if strcmpi(self.driver,'fov_forward'): indices=0 for indep in self.independents: if indep.fos_forward_index: indices+=indep.fov_forward_indices break else: if strcmpi(indep.type,'scalar'): indices+=1 else: indices+=indep.nods indices-=1 #get c-indices numbering going WriteData(fid,prefix,'data',indices,'name','md.autodiff.fov_forward_indices','format','IntMat','mattype',3) #}}} #deal with mass fluxes: {{{ mass_flux_segments=[dep.segments for dep in self.dependents if strcmpi(dep.name,'MassFlux')] if mass_flux_segments: WriteData(fid,prefix,'data',mass_flux_segments,'name','md.autodiff.mass_flux_segments','format','MatArray') flag=True else: flag=False WriteData(fid,prefix,'data',flag,'name','md.autodiff.mass_flux_segments_present','format','Boolean') #}}} #deal with trace keep on: {{{ keep=False #From ADOLC userdoc: # The optional integer argument keep of trace on determines whether the numerical values of all active variables are # recorded in a buffered temporary array or file called the taylor stack. This option takes effect if keep = 1 and # prepares the scene for an immediately following gradient evaluation by a call to a routine implementing the reverse # mode as described in the Section 4 and Section 5. # if len(self.driver)<=3: keep=False #there is no "_reverse" string within the driver string: else: if strncmpi(self.driver[3:],'_reverse',8): keep=True else: keep=False WriteData(fid,prefix,'data',keep,'name','md.autodiff.keep','format','Boolean') #}}} return
# }}}