8 #define MIN(a, b) ( ( a ) > ( b ) ? ( b ) : ( a ) ) 9 #define MAX(a, b) ( ( a ) > ( b ) ? ( a ) : ( b ) ) 16 -1, -1, -1, 0, 0, 1, 1, 1
19 -1, 0, 1, -1, 1, -1, 0, 1
24 true,
false,
true,
false,
false,
true,
false,
true 39 -2, -1, 1, 2, 0, 0, 0, 0
42 0, 0, 0, 0, -2, -1, 1, 2
55 Frozen = (
bool * ) calloc(
m *
n,
sizeof(
bool ) );
97 for (
int ind = 0; ind < (
m *
n ); ind++ ) {
114 OOFEM_ERROR(
"Matrix gridCoords passed to Grid :: setZeroValues should have 2 columns.");
117 for (
int ival = 1; ival <= nValues; ival++ ) {
119 double CPx = gridCoords->
at(ival, 1);
120 double CPy = gridCoords->
at(ival, 2);
122 double j = ( int ) ceil(CPx - 0.5);
125 }
else if ( j >
n ) {
128 double i = ( int ) ceil(CPy - 0.5);
131 }
else if ( i >
m ) {
138 double Fij =
F->
at(i, j);
139 T->
at(i, j) = sqrt( ( i - CPy ) * ( i - CPy ) + ( j - CPx ) * ( j - CPx ) ) / Fij;
148 for (
int neigh = 0; neigh < 4; neigh++ ) {
149 ni = i + iOffsets [ neigh ];
150 nj = j + jOffsets [ neigh ];
154 time = sqrt( ( ni - CPy ) * ( ni - CPy ) + ( nj - CPx ) * ( nj - CPx ) ) / ( 0.5 * ( Fij +
F->
at(ni, nj) ) );
156 time = sqrt( ( ni - CPy ) * ( ni - CPy ) + ( nj - CPx ) * ( nj - CPx ) ) /
F->
at(ni, nj);
159 T->
at(ni, nj) =
MIN( time,
T->
at(ni, nj) );
161 T->
at(ni, nj) = time;
167 for (
int neigh = 0; neigh < 8; neigh++ ) {
168 ni = i + iOffsets_full [ neigh ];
169 nj = j + jOffsets_full [ neigh ];
173 time = sqrt( ( ni - CPy ) * ( ni - CPy ) + ( nj - CPx ) * ( nj - CPx ) ) / ( 0.5 * ( Fij +
F->
at(ni, nj) ) );
175 time = sqrt( ( ni - CPy ) * ( ni - CPy ) + ( nj - CPx ) * ( nj - CPx ) ) /
F->
at(ni, nj);
178 if ( is_diag [ neigh ] ) {
182 T->
at(ni, nj) =
MIN( time,
T->
at(ni, nj) );
184 T->
at(ni, nj) = time;
218 for (
int j = 1; j <=
n; j++ ) {
220 for (
int i = 1; i <=
m; i++ ) {
221 printf(
"%d %d %g\n", j, i,
T->
at(i, j) );
231 int i, j, ni, nj, nInd;
241 for (
int ind = 0; ind < (
m *
n ); ind++ ) {
246 for (
int neigh = 0; neigh < 4; neigh++ ) {
247 ni = i + iOffsets [ neigh ];
248 nj = j + jOffsets [ neigh ];
255 if ( tmpFlag > eFlag ) {
277 for (
int neigh = 0; neigh < 4; neigh++ ) {
278 ni = i + iOffsets [ neigh ];
279 nj = j + jOffsets [ neigh ];
292 if ( tmpFlag > eFlag ) {
309 double Inf = std::numeric_limits<float>::infinity();
315 double CrossVals [ 8 ];
327 double xmin1 = 0., xmin2, ymin1 = 0., ymin2;
330 for (
int iter = 0; iter < 8; iter++ ) {
331 ni = i + icalcOffsets [ iter ];
332 nj = j + jcalcOffsets [ iter ];
335 CrossVals [ iter ] =
T->
at(ni, nj);
337 CrossVals [ iter ] = Inf;
342 if ( ( CrossVals [ 1 ] == Inf ) && ( CrossVals [ 2 ] == Inf ) &&
343 ( CrossVals [ 5 ] == Inf ) && ( CrossVals [ 6 ] == Inf ) ) {
359 if ( !( ( CrossVals [ 1 ] == Inf ) && ( CrossVals [ 2 ] == Inf ) ) ) {
360 ymin1 =
MIN(CrossVals [ 1 ], CrossVals [ 2 ]);
365 if ( CrossVals [ 1 ] < CrossVals [ 2 ] ) {
366 ni = i + icalcOffsets [ 1 ];
367 nj = j + jcalcOffsets [ 1 ];
369 ni = i + icalcOffsets [ 2 ];
370 nj = j + jcalcOffsets [ 2 ];
377 if ( !( ( CrossVals [ 5 ] == Inf ) && ( CrossVals [ 6 ] == Inf ) ) ) {
378 xmin1 =
MIN(CrossVals [ 5 ], CrossVals [ 6 ]);
383 if ( CrossVals [ 5 ] < CrossVals [ 6 ] ) {
384 ni = i + icalcOffsets [ 5 ];
385 nj = j + jcalcOffsets [ 5 ];
387 ni = i + icalcOffsets [ 6 ];
388 nj = j + jcalcOffsets [ 6 ];
399 if ( !( ( CrossVals [ 1 ] == Inf ) && ( CrossVals [ 2 ] == Inf ) ) ) {
400 if ( CrossVals [ 1 ] < CrossVals [ 2 ] ) {
401 ymin1 = CrossVals [ 1 ];
403 ni = i + icalcOffsets [ 1 ];
404 nj = j + jcalcOffsets [ 1 ];
407 if ( CrossVals [ 0 ] <= CrossVals [ 1 ] ) {
408 ymin2 = CrossVals [ 0 ];
410 b += -6. * ymin1 + 1.5 * ymin2;
411 c += 4.0 * ymin1 * ymin1 + 0.25 * ymin2 * ymin2 - 2.0 * ymin1 * ymin2;
418 ymin1 = CrossVals [ 2 ];
420 ni = i + icalcOffsets [ 2 ];
421 nj = j + jcalcOffsets [ 2 ];
424 if ( CrossVals [ 3 ] <= CrossVals [ 2 ] ) {
425 ymin2 = CrossVals [ 3 ];
427 b += -6. * ymin1 + 1.5 * ymin2;
428 c += 4.0 * ymin1 * ymin1 + 0.25 * ymin2 * ymin2 - 2.0 * ymin1 * ymin2;
437 if ( !( ( CrossVals [ 5 ] == Inf ) && ( CrossVals [ 6 ] == Inf ) ) ) {
438 if ( CrossVals [ 5 ] < CrossVals [ 6 ] ) {
439 xmin1 = CrossVals [ 5 ];
441 ni = i + icalcOffsets [ 5 ];
442 nj = j + jcalcOffsets [ 5 ];
445 if ( CrossVals [ 4 ] <= CrossVals [ 5 ] ) {
446 xmin2 = CrossVals [ 4 ];
448 b += -6. * xmin1 + 1.5 * xmin2;
449 c += 4.0 * xmin1 * xmin1 + 0.25 * xmin2 * xmin2 - 2.0 * xmin1 * xmin2;
456 xmin1 = CrossVals [ 6 ];
458 ni = i + icalcOffsets [ 6 ];
459 nj = j + jcalcOffsets [ 6 ];
462 if ( CrossVals [ 7 ] <= CrossVals [ 6 ] ) {
463 xmin2 = CrossVals [ 7 ];
465 b += -6. * xmin1 + 1.5 * xmin2;
466 c += 4.0 * xmin1 * xmin1 + 0.25 * xmin2 * xmin2 - 2.0 * xmin1 * xmin2;
480 }
else if ( Fx >= 0. && Fy >= 0. ) {
481 Faver = 0.5 * Fij + 0.25 * ( Fx + Fy );
482 }
else if ( Fx >= 0. ) {
483 Faver = 0.5 * ( Fij + Fx );
484 }
else if ( Fy >= 0. ) {
485 Faver = 0.5 * ( Fij + Fy );
490 c -= 1. / ( Faver * Faver );
493 double d = ( b * b ) - ( 4.0 * a * c );
496 if ( ( d < 0.0 ) && ( ord == 2 ) ) {
498 time =
calcTime(i, j, Fij, 1, tmpFlag);
499 eFlag =
MAX(1, tmpFlag);
500 }
else if ( ( d < 0.0 ) && ( ord == 1 ) ) {
501 if ( ( CrossVals [ 1 ] == Inf ) && ( CrossVals [ 2 ] == Inf ) ) {
504 if ( ( CrossVals [ 5 ] == Inf ) && ( CrossVals [ 6 ] == Inf ) ) {
509 time =
MIN(xmin1, ymin1) + 1.0 / Fij;
512 time = ( -b + sqrt(d) ) / ( 2.0 * a );
void printSolutionAsData()
int giveNumberOfColumns() const
Returns number of columns of receiver.
double getSmallest(int *Ind)
FloatMatrix * T
Matrix storing the values of the unknown (computed) field (e.g., arrival times)
double giveSolutionValueAt(int i, int j)
Output methods.
int ind2j(int ind, int m)
void unFreeze()
Set all flags to "unfrozen".
double calcTime(int i, int j, double Fij, int ord, int &eFlag)
Auxiliary function that evaluates the tentative value at one grid point, exploited by the fast marchi...
bool solutionAvailable
Flag indicating whether the solution has been computed.
void insert(double time, int Ind)
void fastMarch(int &eFlag)
Fast marching method, solving the eikonal equation.
int ij2ind(int i, int j, int m)
Utility methods.
FloatMatrix * F
Matrix storing the values of the prescribed field (e.g., front velocities)
void setZeroValues(FloatMatrix *gridCoords)
Methods setting the values of the unknown field at selected points (e.g., zero times) ...
Grid(int N, int M)
Constructor (N = horizontal dimension, M = vertical dimension)
int n
Grid dimensions: number of grid nodes horizontally (n) and vertically (m)
Class implementing a heap, which is an auxiliary data structure used for efficient sorting and exploi...
double at(int i, int j) const
Coefficient access function.
void setToEmpty(int N)
Interface with external algorithms (such as fast marching)
int order
Algorithmic parameters.
Implementation of matrix containing floating point numbers.
void setSolutionValueAt(int i, int j, double value)
bool isInDomain(int i, int j, int m, int n)
void update(double time, int Ind)
int ind2i(int ind, int m)
the oofem namespace is to define a context or scope in which all oofem names are defined.
Heap * narrowBand
Heap used for efficient sorting and detection of smallest candidate.
int giveNumberOfRows() const
Returns number of rows of receiver.
bool * Frozen
Array storing indicators of frozen points (at which the solution is already known) ...