Index: ../trunk-jpl/src/m/classes/autodiff.py =================================================================== --- ../trunk-jpl/src/m/classes/autodiff.py (revision 13861) +++ ../trunk-jpl/src/m/classes/autodiff.py (revision 13862) @@ -1,4 +1,6 @@ #module imports +from dependent import * +from independent import * from fielddisplay import fielddisplay from EnumDefinitions import * from checkfield import * @@ -13,32 +15,183 @@ """ #properties - def __init__(self): - # {{{ Properties - self.isautodiff = False + def __init__(self,*args): # {{{ + self.isautodiff = False + self.dependents = [] + self.independents = [] + self.driver = 'fos_forward' - #set defaults - self.setdefaultparameters() + if not len(args): + self.setdefaultparameters() + else: + raise RuntimeError("constructor not supported") + # }}} - #}}} - def __repr__(self): - # {{{ Display - string=' automatic differentiation parameters:' - string="%s\n%s"%(string,fielddisplay(self,'isautodiff','indicates if the automatic differentiation is activated')) - return string - #}}} - def setdefaultparameters(self): - # {{{setdefaultparameters + def __repr__(self): # {{{ + s =" automatic differentiation parameters:" + + 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'") + + return s + # }}} + + def setdefaultparameters(self): # {{{ return self - #}}} + # }}} def checkconsistency(self,md,solution,analyses): # {{{ + + #Early return + if not self.isautodiff: + return md + + #Driver value: + md = checkfield(md,'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 # }}} def marshall(self,fid): # {{{ WriteData(fid,'object',self,'fieldname','isautodiff','format','Boolean') - WriteData(fid,'data',False,'enum',AutodiffMassFluxSegmentsPresentEnum(),'format','Boolean'); - WriteData(fid,'data',False,'enum',AutodiffKeepEnum(),'format','Boolean'); + WriteData(fid,'object',self,'fieldname','driver','format','String') + + #early return + if not self.isautodiff: + WriteData(fid,'data',False,'enum',AutodiffMassFluxSegmentsPresentEnum(),'format','Boolean') + WriteData(fid,'data',False,'enum',AutodiffKeepEnum(),'format','Boolean') + return + + #process dependent variables {{{ + num_dependent_objects=len(self.dependents) + WriteData(fid,'data',num_dependent_objects,'enum',AutodiffNumDependentObjectsEnum(),'format','Integer') + + if num_dependent_objects: + names=numpy.zeros(num_dependent_objects) + types=numpy.zeros(num_dependent_objects) + indices=numpy.zeros(num_dependent_objects) + + for i,dep in enumerate(self.dependents): + names[i]=StringToEnum(dep.name)[0] + types[i]=dep.typetoscalar() + indices[i]=dep.index + + WriteData(fid,'data',names,'enum',AutodiffDependentObjectNamesEnum(),'format','IntMat','mattype',3) + WriteData(fid,'data',types,'enum',AutodiffDependentObjectTypesEnum(),'format','IntMat','mattype',3) + WriteData(fid,'data',indices,'enum',AutodiffDependentObjectIndicesEnum(),'format','IntMat','mattype',3) + #}}} + + #process independent variables {{{ + num_independent_objects=len(self.independents) + WriteData(fid,'data',num_independent_objects,'enum',AutodiffNumIndependentObjectsEnum(),'format','Integer') + + if num_independent_objects: + names=numpy.zeros(num_independent_objects) + types=numpy.zeros(num_independent_objects) + + for i,indep in enumerate(self.independents): + names[i]=StringToEnum(indep.name)[0] + types[i]=indep.typetoscalar() + + WriteData(fid,'data',names,'enum',AutodiffIndependentObjectNamesEnum(),'format','IntMat','mattype',3) + WriteData(fid,'data',types,'enum',AutodiffIndependentObjectTypesEnum(),'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 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,'data',index,'enum',AutodiffFosForwardIndexEnum(),'format','Integer') + #}}} + + #if driver is fos_reverse, build index: {{{ + if strcmpi(self.driver,'fos_reverse'): + index=0 + + for dep in self.dependents: + if not 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,'data',index,'enum',AutodiffFosReverseIndexEnum(),'format','Integer') + end + #}}} + + #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,'data',indices,'enum',AutodiffFovForwardIndicesEnum(),'format','IntMat','mattype',3) + end + #}}} + + #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,'data',mass_flux_segments,'enum',MassFluxSegmentsEnum(),'format','MatArray') + flag=True + else: + flag=False + WriteData(fid,'data',flag,'enum',AutodiffMassFluxSegmentsPresentEnum(),'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,'data',keep,'enum',AutodiffKeepEnum(),'format','Boolean') + #}}} + + return # }}} Index: ../trunk-jpl/src/m/classes/autodiff.m =================================================================== --- ../trunk-jpl/src/m/classes/autodiff.m (revision 13861) +++ ../trunk-jpl/src/m/classes/autodiff.m (revision 13862) @@ -54,10 +54,10 @@ WriteData(fid,'object',obj,'fieldname','driver','format','String'); %early return - if ~obj.isautodiff, - WriteData(fid,'data',false,'enum',AutodiffMassFluxSegmentsPresentEnum,'format','Boolean'); - WriteData(fid,'data',false,'enum',AutodiffKeepEnum,'format','Boolean'); - return; + if ~obj.isautodiff, + WriteData(fid,'data',false,'enum',AutodiffMassFluxSegmentsPresentEnum(),'format','Boolean'); + WriteData(fid,'data',false,'enum',AutodiffKeepEnum(),'format','Boolean'); + return; end %process dependent variables {{{ @@ -117,7 +117,7 @@ end end index=index-1; %get c-index numbering going - WriteData(fid,'data',index,'enum',AutodiffFosForwardIndexEnum(),'format','Integer'); + WriteData(fid,'data',index,'enum',AutodiffFosForwardIndexEnum(),'format','Integer'); end %}}} %if driver is fos_reverse, build index: {{{ @@ -138,7 +138,7 @@ end end index=index-1; %get c-index numbering going - WriteData(fid,'data',index,'enum',AutodiffFosReverseIndexEnum(),'format','Integer'); + WriteData(fid,'data',index,'enum',AutodiffFosReverseIndexEnum(),'format','Integer'); end %}}} %if driver is fov_forward, build indices: {{{ @@ -159,8 +159,7 @@ end end indices=indices-1; %get c-indices numbering going - - WriteData(fid,'data',indices,'enum',AutodiffFovForwardIndicesEnum,'format','IntMat','mattype',3); + WriteData(fid,'data',indices,'enum',AutodiffFovForwardIndicesEnum(),'format','IntMat','mattype',3); end %}}} %deal with mass fluxes: {{{ @@ -172,12 +171,12 @@ end end if ~isempty(mass_flux_segments), - WriteData(fid,'data',mass_flux_segments,'enum',MassFluxSegmentsEnum,'format','MatArray'); + WriteData(fid,'data',mass_flux_segments,'enum',MassFluxSegmentsEnum(),'format','MatArray'); flag=true; - else - flag=false; + else + flag=false; end - WriteData(fid,'data',flag,'enum',AutodiffMassFluxSegmentsPresentEnum,'format','Boolean'); + WriteData(fid,'data',flag,'enum',AutodiffMassFluxSegmentsPresentEnum(),'format','Boolean'); %}}} %deal with trace keep on: {{{ keep=false; @@ -198,7 +197,7 @@ keep=false; end end - WriteData(fid,'data',keep,'enum',AutodiffKeepEnum,'format','Boolean'); + WriteData(fid,'data',keep,'enum',AutodiffKeepEnum(),'format','Boolean'); %}}} end % }}} Index: ../trunk-jpl/src/m/classes/dependent.m =================================================================== --- ../trunk-jpl/src/m/classes/dependent.m (revision 13861) +++ ../trunk-jpl/src/m/classes/dependent.m (revision 13862) @@ -14,35 +14,34 @@ nods = 0; end methods - function obj= dependent(varargin) % {{{ + function obj = dependent(varargin) % {{{ - %use provided options to change fields - options=pairoptions(varargin{:}); + %use provided options to change fields + options=pairoptions(varargin{:}); - obj.name=getfieldvalue(options,'name',''); - obj.type=getfieldvalue(options,'type',''); - obj.exp=getfieldvalue(options,'exp',''); - obj.segments=getfieldvalue(options,'segments',[]); - obj.index=getfieldvalue(options,'index',-1); - obj.nods=getfieldvalue(options,'nods',0); + obj.name=getfieldvalue(options,'name',''); + obj.type=getfieldvalue(options,'type',''); + obj.exp=getfieldvalue(options,'exp',''); + obj.segments=getfieldvalue(options,'segments',[]); + obj.index=getfieldvalue(options,'index',-1); + obj.nods=getfieldvalue(options,'nods',0); - %if name is mass flux: - if strcmpi(obj.name,'MassFlux'), - %make sure that we supplied a file and that it exists! - if exist(obj.exp)~=2, - error('dependent checkconsistency: specified ''exp'' file does not exist!'); - end - %process the file and retrieve segments - mesh=getfieldvalue(options,'mesh'); - obj.segments=MeshProfileIntersection(mesh.elements,mesh.x,mesh.y,obj.exp); - end - end - %}}} + %if name is mass flux: + if strcmpi(obj.name,'MassFlux'), + %make sure that we supplied a file and that it exists! + if exist(obj.exp)~=2, + error('dependent checkconsistency: specified ''exp'' file does not exist!'); + end + %process the file and retrieve segments + mesh=getfieldvalue(options,'mesh'); + obj.segments=MeshProfileIntersection(mesh.elements,mesh.x,mesh.y,obj.exp); + end + end + %}}} function obj = setdefaultparameters(obj) % {{{ - %do nothing + %do nothing end % }}} function md = checkconsistency(obj,md,solution,analyses) % {{{ - %do nothing for now if strcmpi(obj.name,'MassFlux'), if isempty(obj.segments), error('dependent checkconsistency error: need segments to compute this dependent response'); @@ -56,14 +55,13 @@ error('cannot declare a dependent with a fos_reverse_index when the driver is not fos_reverse!'); end if obj.nods==0, - error('ependent checkconsistency error: nods should be set to the size of the independent variable'); + error('dependent checkconsistency error: nods should be set to the size of the independent variable'); end - end end % }}} function disp(obj) % {{{ - disp(sprintf(' dependent variable :')); + disp(sprintf(' dependent variable:')); fielddisplay(obj,'name','variable name (must match corresponding Enum)'); fielddisplay(obj,'type','type of variable (''vertex'' or ''scalar'')'); @@ -78,11 +76,11 @@ end % }}} function scalar=typetoscalar(obj) % {{{ - if strcmpi(obj.type,'scalar'), - scalar=0; - elseif strcmpi(obj.type,'vertex'), - scalar=1; - end + if strcmpi(obj.type,'scalar'), + scalar=0; + elseif strcmpi(obj.type,'vertex'), + scalar=1; + end end % }}} end Index: ../trunk-jpl/src/m/classes/independent.py =================================================================== --- ../trunk-jpl/src/m/classes/independent.py (revision 0) +++ ../trunk-jpl/src/m/classes/independent.py (revision 13862) @@ -0,0 +1,75 @@ +from pairoptions import * +from MatlabFuncs import * +from EnumDefinitions import * +from WriteData import * + +class independent(object): + """ + INDEPENDENT class definition + + Usage: + independent=independent(); + """ + + def __init__(self,*args): # {{{ + self.name = '' + self.type = '' + self.fos_forward_index = float('NaN') + self.fov_forward_indices = numpy.array([]) + self.nods = 0 + + #set defaults + self.setdefaultparameters() + + #use provided options to change fields + options=pairoptions(*args) + + #OK get other fields + self=options.AssignObjectFields(self) + # }}} + + def setdefaultparameters(self): # {{{ + #do nothing + return self + # }}} + + def checkconsistency(self,md,i,solution,analyses,driver): # {{{ + if not isnan(self.fos_forward_index): + if not strcmpi(driver,'fos_forward'): + raise TypeError("cannot declare an independent with a fos_forward_index when the driver is not fos_forward!") + if self.nods==0: + raise TypeError("independent checkconsistency error: nods should be set to the size of the independent variable") + + if self.fov_forward_indices: + if not strcmpi(driver,'fov_forward'): + raise TypeError("cannot declare an independent with fov_forward_indices when the driver is not fov_forward!") + if self.nods==0: + raise TypeError("independent checkconsistency error: nods should be set to the size of the independent variable") + end + md = checkfield(md,"autodiff.independents[%d].fov_forward_indices" % i,'>=',1,'<=',self.nods,'size',[float('NaN'),1]) + + return md + # }}} + + def __repr__(self): # {{{ + s =" independent variable:\n" + + s+="%s\n" % fielddisplay(self,'name',"variable name (must match corresponding Enum)") + s+="%s\n" % fielddisplay(self,'type',"type of variable ('vertex' or 'scalar')") + if not isnan(self.fos_forward_index): + s+="%s\n" % fielddisplay(self,'fos_forward_index',"index for fos_foward driver of ADOLC") + if numpy.any(numpy.logical_not(numpy.isnan(self.fov_forward_indices))): + s+="%s\n" % fielddisplay(self,'fov_forward_indices',"indices for fov_foward driver of ADOLC") + + return s + # }}} + + def typetoscalar(self): # {{{ + if strcmpi(self.type,'scalar'): + scalar=0 + elif strcmpi(self.type,'vertex'): + scalar=1 + + return scalar + # }}} + Index: ../trunk-jpl/src/m/classes/independent.m =================================================================== --- ../trunk-jpl/src/m/classes/independent.m (revision 13861) +++ ../trunk-jpl/src/m/classes/independent.m (revision 13862) @@ -12,22 +12,21 @@ nods = 0; end methods - function obj= independent(varargin) % {{{ + function obj = independent(varargin) % {{{ - %use provided options to change fields - options=pairoptions(varargin{:}); + %use provided options to change fields + options=pairoptions(varargin{:}); - %OK get other fields - obj=AssignObjectFields(pairoptions(varargin{:}),obj); + %OK get other fields + obj=AssignObjectFields(pairoptions(varargin{:}),obj); - end - %}}} + end + %}}} function obj = setdefaultparameters(obj) % {{{ %do nothing end % }}} function md = checkconsistency(obj,md,i,solution,analyses,driver) % {{{ - %do nothing for now if ~isnan(obj.fos_forward_index), if ~strcmpi(driver,'fos_forward'), error('cannot declare an independent with a fos_forward_index when the driver is not fos_forward!'); @@ -41,7 +40,6 @@ if ~strcmpi(driver,'fov_forward'), error('cannot declare an independent with fov_forward_indices when the driver is not fov_forward!'); end - if obj.nods==0, error('independent checkconsistency error: nods should be set to the size of the independent variable'); end @@ -50,7 +48,7 @@ end % }}} function disp(obj) % {{{ - disp(sprintf(' independent variable :')); + disp(sprintf(' independent variable:')); fielddisplay(obj,'name','variable name (must match corresponding Enum)'); fielddisplay(obj,'type','type of variable (''vertex'' or ''scalar'')'); Index: ../trunk-jpl/src/m/classes/dependent.py =================================================================== --- ../trunk-jpl/src/m/classes/dependent.py (revision 0) +++ ../trunk-jpl/src/m/classes/dependent.py (revision 13862) @@ -0,0 +1,94 @@ +import os.path +from pairoptions import * +from MatlabFuncs import * +from EnumDefinitions import * +from WriteData import * +#from MeshProfileIntersection import * + +class dependent(object): + """ + DEPENDENT class definition + + Usage: + dependent=dependent(); + """ + + def __init__(self,*args): # {{{ + self.name = '' + self.type = '' + self.fos_reverse_index = float('NaN') + self.exp = '' + self.segments = [] + self.index = -1 + self.nods = 0 + + #set defaults + self.setdefaultparameters() + + #use provided options to change fields + options=pairoptions(*args) + + self.name=options.getfieldvalue('name','') + self.type=options.getfieldvalue('type','') + self.exp=options.getfieldvalue('exp','') + self.segments=options.getfieldvalue('segments',[]) + self.index=options.getfieldvalue('index',-1) + self.nods=options.getfieldvalue('nods',0) + + #if name is mass flux: + if strcmpi(self.name,'MassFlux'): + #make sure that we supplied a file and that it exists! + if not os.path.exists(self.exp): + raise IOError("dependent checkconsistency: specified 'exp' file does not exist!") + #process the file and retrieve segments + mesh=options.getfieldvalue('mesh') + raise RuntimeError("MeshProfileIntersection is not complete.") + self.segments=MeshProfileIntersection(mesh.elements,mesh.x,mesh.y,self.exp) + # }}} + + def setdefaultparameters(self): # {{{ + #do nothing + return self + # }}} + + def checkconsistency(self,md,solution,analyses): # {{{ + if strcmpi(self.name,'MassFlux'): + if not self.segments: + raise RuntimeError("dependent checkconsistency error: need segments to compute this dependent response") + if self.index<0: + raise RuntimeError("dependent checkconsistency error: index for segments should be >=0") + + if not isnan(self.fos_reverse_index): + if not strcmpi(driver,'fos_reverse'): + raise TypeError("cannot declare a dependent with a fos_reverse_index when the driver is not fos_reverse!") + if self.nods==0: + raise TypeError("dependent checkconsistency error: nods should be set to the size of the independent variable") + + return md + # }}} + + def __repr__(self): # {{{ + s =" dependent variable:\n" + + s+="%s\n" % fielddisplay(self,'name',"variable name (must match corresponding Enum)") + s+="%s\n" % fielddisplay(self,'type',"type of variable ('vertex' or 'scalar')") + + if not isnan(self.fos_reverse_index): + s+="%s\n" % fielddisplay(self,'fos_reverse_index',"index for fos_reverse driver of ADOLC") + end + if self.exp: + s+="%s\n" % fielddisplay(self,'exp',"file needed to compute dependent variable") + s+="%s\n" % fielddisplay(self,'segments',"mass flux segments") + + return s + # }}} + + def typetoscalar(self): # {{{ + if strcmpi(self.type,'scalar'): + scalar=0 + elif strcmpi(self.type,'vertex'): + scalar=1 + + return scalar + # }}} +