1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
#include "AdunKernel/AdunConfigurationGenerator.h"
@implementation AdConfigurationGenerator
- (void) checkFloatingPointErrors
{
int raised;
NSMutableDictionary* errorInfo;
NSError* error;
/*
* We want to detect floating point errors since they
* will affect the stability of our simulation.
* The errors we are detecting are based on IEEE754 standard
* 1 - Invalid Operation
* 2 - Division by Zero
* 3 - Overflow
* 4 - Underflow
* 5 - Inexact
* However error 5 is common since all irrational and transcendental
* numbers are inexact and we may be adding many numbers who differ by more than
* DBL_EPSILON so we wont do anything in this case .
* Error 4 leads to a slow loss of precision - however it may occur
* that tiny forces and energies are calculated in the course of
* a simulation. In this case we will just log when this happens and
* let Error 2 handle cases where this will lead to a catastrophic error
* (due to the result being zero).
* See the Arithmetic section of the libc manual for more detail.
*/
raised = fetestexcept(AdFloatingPointExceptionMask);
#ifdef FE_INVALID
if(raised & FE_INVALID)
{
errorInfo = [NSMutableDictionary dictionary];
[errorInfo setObject: @"Detected floating point exception during simulation."
forKey: NSLocalizedDescriptionKey];
[errorInfo setObject: @"Exception due to an invalid operation."
forKey: @"AdDetailedDescriptionKey"];
[errorInfo setObject: @"This is a critical error and likely due to a bug in an underlying algorithm.\n\
Please contact the Adun developers with information regarding the simulation you were running when this occurred.\n\
(Options, System, Results etc)\n"
forKey: @"NSRecoverySuggestionKey"];
error = [NSError errorWithDomain: AdunKernelErrorDomain
code: AdKernelFloatingPointError
userInfo: errorInfo];
feclearexcept(FE_ALL_EXCEPT);
[[NSException exceptionWithName: @"AdFloatingPointException"
reason: @"Caught a IEEE74 floating point exception"
userInfo: [NSDictionary dictionaryWithObject: error
forKey: @"AdKnownExceptionError"]]
raise];
}
#endif
#ifdef FE_OVERFLOW
if(raised & FE_OVERFLOW)
{
errorInfo = [NSMutableDictionary dictionary];
[errorInfo setObject: @"Detected floating point exception during simulation."
forKey: NSLocalizedDescriptionKey];
[errorInfo setObject: @"Exception due to overflow"
forKey: @"AdDetailedDescriptionKey"];
[errorInfo setObject: @"This error indicates infinities entering the simulation.\n\
This is likely an indication of the simulation exploding due to excessive forces.\nUnrelaxed starting structures are\
a possible explanation.\nIn this case it is recommended you run an initial simulation with a smaller time step to relax\
the molecule.\nIt is also recommened that you examine the data collected so far which will provide more information on\
the cause.\n)"
forKey: @"NSRecoverySuggestionKey"];
error = [NSError errorWithDomain: AdunKernelErrorDomain
code: AdKernelFloatingPointError
userInfo: errorInfo];
feclearexcept(FE_ALL_EXCEPT);
[[NSException exceptionWithName: @"AdFloatingPointException"
reason: @"Caught a IEEE74 floating point exception"
userInfo: [NSDictionary dictionaryWithObject: error
forKey: @"AdKnownExceptionError"]]
raise];
}
#endif
#ifdef FE_DIVBYZERO
if(raised & FE_DIVBYZERO)
{
errorInfo = [NSMutableDictionary dictionary];
[errorInfo setObject: @"Detected floating point exception during simulation."
forKey: NSLocalizedDescriptionKey];
[errorInfo setObject: @"Exception due to divide by zero"
forKey: @"AdDetailedDescriptionKey"];
[errorInfo setObject: @"This error could be due to a underflow event or a programming bug.\n\
Please contact the Adun developers with information regarding the simulation you were running when this occurred.\n\
(Options, System, Results etc)\n"
forKey: @"NSRecoverySuggestionKey"];
error = [NSError errorWithDomain: AdunKernelErrorDomain
code: AdKernelFloatingPointError
userInfo: errorInfo];
feclearexcept(FE_ALL_EXCEPT);
[[NSException exceptionWithName: @"AdFloatingPointException"
reason: @"Caught a IEEE74 floating point exception"
userInfo: [NSDictionary dictionaryWithObject: error
forKey: @"AdKnownExceptionError"]]
raise];
}
#endif
#ifdef FE_UNDERFLOW
if(raised & FE_UNDERFLOW)
{
NSWarnLog(@"Detected an underflow exception.");
NSWarnLog(@"This could be the result of extremly small forces and/or energies being calculated.");
NSWarnLog(@"Such events are not uncommon but will lead to a loss of precision.");
NSWarnLog(@"It is possible that underflows could lead to zeros entering the calculation and\
'divide by zero' errors as a result\n. However these will be caught independantly if they occur");
NSWarnLog(@"Continuing simulation");
feclearexcept(FE_ALL_EXCEPT);
}
#endif
//clear any FE_INEXACT exceptions
feclearexcept(FE_ALL_EXCEPT);
}
- (BOOL) production: (NSError**) error
{
NSWarnLog(@"Abstract method. You should only initialise a concrete subclass of %@",
NSStringFromClass([self class]));
}
- (BOOL) restartFrom: (int) step error: (NSError**) error
{
NSWarnLog(@"Abstract method. You should only initialise a concrete subclass of %@",
NSStringFromClass([self class]));
}
- (void) endProduction
{
NSWarnLog(@"Abstract method. You should only initialise a concrete subclass of %@",
NSStringFromClass([self class]));
}
- (unsigned int) numberOfSteps
{
NSWarnLog(@"Abstract method. You should only initialise a concrete subclass of %@",
NSStringFromClass([self class]));
}
- (void) setNumberOfSteps: (unsigned int) aNumber
{
NSWarnLog(@"Abstract method. You should only initialise a concrete subclass of %@",
NSStringFromClass([self class]));
}
- (unsigned int) currentStep
{
NSWarnLog(@"Abstract method. You should only initialise a concrete subclass of %@",
NSStringFromClass([self class]));
}
- (AdSystemCollection*) systems
{
NSWarnLog(@"%@ is an abstract method. You should only initialise a concrete subclass of %@",
NSStringFromSelector(_cmd),
NSStringFromClass([self class]));
}
- (AdForceFieldCollection*) forceFields
{
NSWarnLog(@"%@ is an abstract method. You should only initialise a concrete subclass of %@",
NSStringFromSelector(_cmd),
NSStringFromClass([self class]));
}
@end
|