Logo Search packages:      
Sourcecode: adun.app version File versions  Download package

AdunInteractionSystem.m

/*
   Project: Adun

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   This application is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This application is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include "AdunKernel/AdunInteractionSystem.h"

00024 @implementation AdInteractionSystem

- (AdMatrix*) _combineMatrix: (AdMatrix*) matrixOne
            withMatrix: (AdMatrix*) matrixTwo
{
      int i;
      AdMatrix* dest;
      
      dest = (AdMatrix*)malloc(sizeof(AdMatrix));
      dest->no_rows = matrixOne->no_rows + matrixTwo->no_rows;
      dest->no_columns = matrixOne->no_columns;
      dest->matrix = (double**)malloc(dest->no_rows*sizeof(double*));

      for(i=0; i < matrixOne->no_rows; i++)
            dest->matrix[i] = matrixOne->matrix[i];
      
      for(i=matrixOne->no_rows; i < dest->no_rows; i++)
            dest->matrix = matrixTwo->matrix[i-matrixOne->no_rows];

      return dest;
}

- (InterTable*) _combineTable: (InterTable*) matrixOne
            withTable: (InterTable*) matrixTwo
{
      int i;
      InterTable* dest;
      
      dest = (InterTable*)malloc(sizeof(InterTable));
      dest->no_interactions = matrixOne->no_interactions + matrixTwo->no_interactions;
      dest->no_columns = matrixOne->no_columns;
      dest->table = (double**)malloc(dest->no_interactions*sizeof(double*));

      for(i=0; i < matrixOne->no_interactions; i++)
            dest->table[i] = matrixOne->table[i];
      
      for(i=matrixOne->no_interactions; i < dest->no_interactions; i++)
            dest->table = matrixTwo->table[i-matrixOne->no_interactions];

      return dest;
}

//combine the necessary matrices

- (void) _createCombinedSystem
{     
      InterTable* combinedVDW;
      id subOneParams, subTwoParams;

      //create a combination coordinate velocity and acceleration matrix 
      
      combinedCoordinates = [self _combineMatrix: 
                              [[subsystemOne valueForKeyPath:@"dynamics.coordinates"] pointerValue]
                         withMatrix: [[subsystemTwo valueForKeyPath:@"dynamics.coordinates"] pointerValue]];
      combinedVelocities = [self _combineMatrix:
                               [[subsystemOne valueForKeyPath:@"dynamics.velocities"] pointerValue]
                         withMatrix: [[subsystemTwo valueForKeyPath:@"dynamics.velocities"] pointerValue]];
      combinedAccelerations = [self _combineMatrix:
                               [[subsystemOne valueForKeyPath:@"dynamics.accelerations"] pointerValue]
                         withMatrix: [[subsystemTwo valueForKeyPath:@"dynamics.accelerations"] pointerValue]];
      
      //combine the nonbondedParameters - just VDW for the moment

      subOneParams = [subsystemOne valueForKeyPath:
                        @"shortRangeNonbondedTopology.nonbondedInteractionTypes.TypeOneVDWInteraction"];
      subTwoParams = [subsystemTwo valueForKeyPath:
                        @"shortRangeNonbondedTopology.nonbondedInteractionTypes.TypeOneVDWInteraction"];
      combinedVDW = [self _combineTable: [subOneParams pointerValue] withTable: [subTwoParams pointerValue]];
      
      [nonbondedInteractionTypes setValue: [NSValue valueWithPointer: combinedVDW] forKey: TypeOneVDWInteraction];
      [nonbondedInteractionTypes setValue: [NSNull null] forKey: CoulombElectrostatic];
}

//create the interaction list

- (void) _createSubsystemsInteractions
{
      int i, subsystemTwoAtoms, subsystemOneAtoms;
      NSMutableIndexSet* indexes;
      NSRange indexRange;

      subsystemOneAtoms = [[subsystemOne valueForKeyPath:@"dynamics.numberOfAtoms"] intValue];
      subsystemTwoAtoms = [[subsystemTwo valueForKeyPath:@"dynamics.numberOfAtoms"] intValue];
      numberOfAtoms = subsystemOneAtoms + subsystemTwoAtoms;      

      for(i=0; i<subsystemOneAtoms; i++)
      {
            indexRange.location = subsystemOneAtoms;
            indexRange.length = numberOfAtoms - indexRange.location;
            indexes = [NSMutableIndexSet indexSetWithIndexesInRange: indexRange];
            [nonbondedInteractions addObject: indexes];
      }
}

/*********************

Object Creation

**********************/

- (void) _useEnvironmentDefaults
{
      //no defaults
}

00129 - (id) initWithEnvironment: (id) object observe: (BOOL) value
{
      if(self = [super initWithEnvironment: object observe: value])
      {
            systemKeywords = [NSMutableArray arrayWithObjects: 
                              @"Interaction",
                              nil];
            [systemKeywords retain];
            //this ivar is temporary until AdInteractionSystem can handle bonded interactions
            bondedTopology = [NSMutableDictionary new];
            shortRangeNonbondedTopology = [[AdNonBondedTopology alloc] 
                                    initWithEnvironment: environment];
            nonbondedInteractions = [NSMutableArray new];
            nonbondedInteractionTypes = [NSMutableDictionary new];
                  allowedStates = [[NSArray alloc] initWithObjects:
                              @"Active", 
                              @"Inactive", 
                              nil];

            status = @"Active";
            [status retain];

            if(environment != nil)
            {
                  [self synchroniseWithEnvironment];
                  [self registerWithEnvironment];
            }
            else
                  [self _useEnvironmentDefaults];

            dataLoaded = NO;  
      }
      
      return self;
}

00165 - (id) initWithEnvironment: (id) object
{
      return [self initWithEnvironment: object observe: YES];
}

- (id) init
{
      return [self initWithEnvironment: nil];
}

- (void) _cleanUp
{
      InterTable* vdwInteraction;
      
      if(!dataLoaded)
            return;
      
      vdwInteraction = [[nonbondedInteractionTypes valueForKey: TypeOneVDWInteraction] pointerValue];
      free(combinedCoordinates->matrix);  
      free(combinedCoordinates);
      free(combinedVelocities->matrix);   
      free(combinedVelocities);
      free(combinedAccelerations->matrix);      
      free(combinedAccelerations);
      free(vdwInteraction->table);
      free(vdwInteraction);
}

- (void) dealloc
{
      [self _cleanUp];
      [state clearTimer];
      [state release];
      [bondedTopology release];
      [shortRangeNonbondedTopology release];
      [nonbondedInteractions release];
      [nonbondedInteractionTypes release];
      [systemKeywords release];
      [allowedStates release];
      [status release];
      [super dealloc];
}

- (void) handleDataSourceContentsChange: (NSNotification*) aNotification
{
      //if the contents of our data sources changed then rebuild all 
      //interactions

      [self _cleanUp];
      [self _createCombinedSystem];
      [self _createSubsystemsInteractions];
      [shortRangeNonbondedTopology reloadData];
      [state updateSystemData];
}

/*****************

Updating

*******************/

- (void) frameUpdate
{
      [state frameUpdate];
}

- (void) update
{
      NSDebugLLog(@"AdInteractionSystem", @"(%@) This method does nothing %@", 
            [self class], 
            NSStringFromSelector(_cmd));
}

/*******************

DataSource delegation

********************/

//FIXME: Need to be more rigourous
00245 - (void) setDataSource: (id) object;
{
      //remove ourselves from observing all current 
      //AdSystemContentsDidChangeNotification's 
      [notificationCenter removeObserver: self
            name: @"AdSystemContentsDidChangeNotification"
            object: nil];

      dataSource = object;
      [notificationCenter addObserver: self
            selector: @selector(handleDataSourceContentsChange:)
            name: @"AdSystemContentsDidChangeNotification"
            object: [dataSource objectAtIndex: 0]];
      [notificationCenter addObserver: self
            selector: @selector(handleDataSourceContentsChange:)
            name: @"AdSystemContentsDidChangeNotification"
            object: [dataSource objectAtIndex: 1]];
}
      
00264 - (id) dataSource
{
      return dataSource;
}

00269 - (void) reloadData
{
      //clean up variables created by any previous reloadData calls

      [self _cleanUp];

      subsystemOne = [dataSource objectAtIndex: 0];
      subsystemTwo = [dataSource objectAtIndex: 1];
      [self _createCombinedSystem];
      [self _createSubsystemsInteractions];
      
      [shortRangeNonbondedTopology setDataSource: self];
      [shortRangeNonbondedTopology reloadData];
      
      if(state == nil)
            state = [[AdState alloc] initWithEnvironment: environment system: self];
      else
            [state updateSystemData];
      
      [state setKineticUpdate: NO];

      dataLoaded = YES;
}

/*
 * Environment observation
 */

00297 - (void) updateForKey: (NSString*) key value: (id) value object: (id) object
{
      //no updates as of yet
}

00302 - (void) registerWithEnvironment
{
      //nothing to register
}

00307 - (void) deregisterWithEnvironment
{
      //nothing to deregister
}

00312 - (void) synchroniseWithEnvironment
{
      //nothing to retrieve
}

00317 - (void) setEnvironment: (id) object
{
      [self deregisterWithEnvironment];
      object = environment;
      [self registerWithEnvironment];
}


/********************

NonbondedTopologyDataSource Methods

**********************/

- (NSValue*) objectValueForCoordinates: (id) object
{
      return [NSValue valueWithPointer: combinedCoordinates];
}

00336 - (NSArray*) objectValueForNonbondedInteractions: (id) object
{
      return nonbondedInteractions;
}

00341 - (NSDictionary*) objectValueForNonbondedInteractionTypes: (id) object
{
      return [nonbondedInteractionTypes copy];
}

/*****************

Coding

*******************/

- (id) initWithCoder: (NSCoder*) decoder
{
      self = [super initWithCoder: decoder];
      if([decoder allowsKeyedCoding])
      {
            dataSource = [decoder decodeObjectForKey: @"DataSource"];
            subsystemOne = [dataSource objectAtIndex: 0];
            subsystemTwo = [dataSource objectAtIndex: 1];
            nonbondedInteractions = [NSMutableArray new];
            nonbondedInteractionTypes = [NSMutableDictionary new];
            [self _createCombinedSystem];
            [self _createSubsystemsInteractions];
            systemKeywords = [decoder decodeObjectForKey: @"SystemKeywords"];
            state = [decoder decodeObjectForKey: @"State"]; 
            shortRangeNonbondedTopology = [decoder decodeObjectForKey: @"ShortRangeNonbondedTopology"];
            [shortRangeNonbondedTopology retain];
            [state retain];
            [systemKeywords retain];      
            bondedTopology = [NSMutableDictionary new];
            status = [decoder decodeObjectForKey: @"Status"];
            [status retain];
            allowedStates = [[NSArray alloc] initWithObjects:
                              @"Active", 
                              @"Inactive", 
                              nil];

            environment = [AdEnvironment globalEnvironment];
            if(environment != nil)
            {
                  [self synchroniseWithEnvironment];
                  [self registerWithEnvironment];
            }
            else
                  [self _useEnvironmentDefaults];

      }
      else
            [NSException raise: NSInvalidArgumentException
                  format: @"%@ class does not support non keyed coding", [self class]];
            

      return self;
}

- (void) encodeWithCoder: (NSCoder*) encoder
{
      [super encodeWithCoder: encoder];
      if([encoder allowsKeyedCoding])
      {
            [encoder encodeObject: shortRangeNonbondedTopology 
                  forKey: @"ShortRangeNonbondedTopology"];
            [encoder encodeObject: state forKey: @"State"];
            [encoder encodeConditionalObject:  dataSource
                  forKey: @"DataSource"];
            [encoder encodeObject: systemKeywords forKey: @"SystemKeywords"]; 
            [encoder encodeObject: status forKey: @"Status"];
      }
      else
            [NSException raise: NSInvalidArgumentException
                  format: @"%@ class does not support non keyed coding", [self class]];
}

/*********************

Accessors

**********************/

- (NSValue*) coordinates
{
      return [NSValue valueWithPointer: combinedCoordinates];     
}

- (NSValue*) velocities
{
      return [NSValue valueWithPointer: combinedVelocities];      
}

- (NSValue*) accelerations
{
      return [NSValue valueWithPointer: combinedAccelerations];   
}

/****

bondedTopology is an empty dict for now

*****/

- (id) dynamics
{
      return nil;
}

- (id) bondedTopology
{
      return nil;
}

- (id) shortRangeNonbondedTopology
{
      return shortRangeNonbondedTopology;
}

- (id) longRangeNonbondedTopology
{
      return nil;
}

- (id) state
{
      return state;
}

- (NSDictionary*) bondedInteractions
{
      return bondedTopology;
}

- (NSDictionary*) nonbondedInteractionTypes
{
      return [shortRangeNonbondedTopology valueForKey: @"nonbondedInteractionTypes"];
}

- (NSValue*) shortRangeNonbondedInteractions
{
      return [shortRangeNonbondedTopology valueForKey:@"nonbondedInteractions"];
}

- (NSValue*) longRangeNonbondedInteractions
{
      return [longRangeNonbondedTopology valueForKey:@"nonbondedInteractions"];
}

- (id) systemKeywords
{
      return systemKeywords;
}

- (NSString*) systemName
{
      return [NSString stringWithFormat: @"%@%@Interaction", 
                  [[dataSource objectAtIndex: 0] systemName],
                  [[dataSource objectAtIndex: 1] systemName]];
}

- (void) setCurrentForceFieldState: (id) forceFieldState
{
      [state setCurrentForceFieldState: forceFieldState];
}

- (NSString*) status
{
      return status;
}

- (void) setStatus: (NSString*) aString
{
      NSMutableDictionary* userInfo;

      if(![allowedStates containsObject: aString])
            [NSException raise: NSInvalidArgumentException
                  format: @"Requested status %@ not valid", aString];

      //If the requested status is the same as the current status
      //do nothing
      if([aString isEqual: status])
            return;

      //If we are being activated but either of the dataSources are inactive
      //raise an NSInternalInconsistencyException

      if([aString isEqual: @"Active"])
      {
            if([[dataSource objectAtIndex: 0] isEqual: @"Inactive"]
                  || [[dataSource objectAtIndex: 1] isEqual: @"Inactive"])
            {
                  [NSException raise: NSInternalInconsistencyException
                        format: @"Cannot activate an interaction system when either of its consituent systems\
is inactive."];
            }
      }

      userInfo = [NSMutableDictionary dictionary];
      [userInfo setObject: status forKey: @"PreviousStatus"]; 
      [status release];
      
      status = [aString retain];
      [userInfo setObject: status forKey: @"CurrentStatus"]; 
      
      [notificationCenter postNotificationName: @"AdSystemStatusDidChangeNotification"
            object: self
            userInfo: userInfo];
}

@end

Generated by  Doxygen 1.6.0   Back to index