172 |
|
|
173 |
|
|
174 |
|
|
175 |
+ |
|
176 |
+ |
|
177 |
+ |
|
178 |
|
void distribPhotonContrib (PhotonMap* pm, unsigned numProc) |
179 |
|
{ |
180 |
|
EmissionMap emap; |
361 |
|
|
362 |
|
/* Seed RNGs from PID for decorellated photon distribution */ |
363 |
|
pmapSeed(randSeed + proc, partState); |
364 |
< |
pmapSeed(randSeed + proc, emitState); |
365 |
< |
pmapSeed(randSeed + proc, cntState); |
366 |
< |
pmapSeed(randSeed + proc, mediumState); |
367 |
< |
pmapSeed(randSeed + proc, scatterState); |
368 |
< |
pmapSeed(randSeed + proc, rouletteState); |
364 |
> |
pmapSeed(randSeed + (proc + 1) % numProc, emitState); |
365 |
> |
pmapSeed(randSeed + (proc + 2) % numProc, cntState); |
366 |
> |
pmapSeed(randSeed + (proc + 3) % numProc, mediumState); |
367 |
> |
pmapSeed(randSeed + (proc + 4) % numProc, scatterState); |
368 |
> |
pmapSeed(randSeed + (proc + 5) % numProc, rouletteState); |
369 |
> |
|
370 |
> |
#ifdef PMAP_SIGUSR |
371 |
> |
double partNumEmit; |
372 |
> |
unsigned long partEmitCnt; |
373 |
> |
double srcPhotonFlux, avgPhotonFlux; |
374 |
> |
unsigned portCnt, passCnt, prePassCnt; |
375 |
> |
float srcPreDistrib; |
376 |
> |
double srcNumEmit; /* # to emit from source */ |
377 |
> |
unsigned long srcNumDistrib; /* # stored */ |
378 |
> |
|
379 |
> |
void sigUsrDiags() |
380 |
> |
/* Loop diags via SIGUSR1 */ |
381 |
> |
{ |
382 |
> |
sprintf(errmsg, |
383 |
> |
"********************* Proc %d Diags *********************\n" |
384 |
> |
"srcIdx = %d (%s)\nportCnt = %d (%s)\npassCnt = %d\n" |
385 |
> |
"srcFlux = %f\nsrcPhotonFlux = %f\navgPhotonFlux = %f\n" |
386 |
> |
"partNumEmit = %f\npartEmitCnt = %lu\n\n", |
387 |
> |
proc, srcIdx, findmaterial(source [srcIdx].so) -> oname, |
388 |
> |
portCnt, photonPorts [portCnt].so -> oname, |
389 |
> |
passCnt, srcFlux [srcIdx], srcPhotonFlux, avgPhotonFlux, |
390 |
> |
partNumEmit, partEmitCnt); |
391 |
> |
eputs(errmsg); |
392 |
> |
fflush(stderr); |
393 |
> |
} |
394 |
> |
#endif |
395 |
|
|
396 |
+ |
#if PMAP_SIGUSR |
397 |
+ |
signal(SIGUSR1, sigUsrDiags); |
398 |
+ |
#endif |
399 |
+ |
|
400 |
+ |
/* Output child process PID after random delay to prevent corrupted |
401 |
+ |
* console output due to race condition */ |
402 |
+ |
usleep(1e6 * pmapRandom(rouletteState)); |
403 |
+ |
fprintf(stderr, "Proc %d: PID = %d\n", proc, getpid()); |
404 |
+ |
/* Allow time for debugger to attach to child process */ |
405 |
+ |
sleep(10); |
406 |
+ |
|
407 |
|
/* ============================================================= |
408 |
|
* 2-PASS PHOTON DISTRIBUTION |
409 |
|
* Pass 1 (pre): emit fraction of target photon count |
412 |
|
* count |
413 |
|
* ============================================================= */ |
414 |
|
for (srcIdx = 0; srcIdx < nsources; srcIdx++) { |
415 |
+ |
#ifndef PMAP_SIGUSR |
416 |
|
unsigned portCnt, passCnt = 0, prePassCnt = 0; |
417 |
|
float srcPreDistrib = preDistrib; |
418 |
|
double srcNumEmit = 0; /* # to emit from source */ |
419 |
|
unsigned long srcNumDistrib = pm -> numPhotons; /* # stored */ |
420 |
+ |
#else |
421 |
+ |
passCnt = prePassCnt = 0; |
422 |
+ |
srcPreDistrib = preDistrib; |
423 |
+ |
srcNumEmit = 0; /* # to emit from source */ |
424 |
+ |
srcNumDistrib = pm -> numPhotons; /* # stored */ |
425 |
+ |
#endif |
426 |
|
|
427 |
|
if (srcFlux [srcIdx] < FTINY) |
428 |
|
continue; |
430 |
|
while (passCnt < 2) { |
431 |
|
if (!passCnt) { |
432 |
|
/* INIT PASS 1 */ |
433 |
< |
if (++prePassCnt > maxPreDistrib && !proc) { |
433 |
> |
if (++prePassCnt > maxPreDistrib) { |
434 |
|
/* Warn if no photons contributed after sufficient |
435 |
|
* iterations; only output from subprocess 0 to reduce |
436 |
|
* console clutter */ |
437 |
< |
sprintf(errmsg, |
438 |
< |
"source %s: too many prepasses, skipped", |
439 |
< |
source [srcIdx].so -> oname); |
440 |
< |
error(WARNING, errmsg); |
437 |
> |
if (!proc) { |
438 |
> |
sprintf(errmsg, |
439 |
> |
"source %s: too many prepasses, skipped", |
440 |
> |
source [srcIdx].so -> oname); |
441 |
> |
error(WARNING, errmsg); |
442 |
> |
} |
443 |
> |
|
444 |
|
break; |
445 |
|
} |
446 |
|
|
449 |
|
} |
450 |
|
else { |
451 |
|
/* INIT PASS 2 */ |
452 |
+ |
#ifndef PMAP_SIGUSR |
453 |
|
double srcPhotonFlux, avgPhotonFlux; |
454 |
+ |
#endif |
455 |
|
|
456 |
|
/* Based on the outcome of the predistribution we can now |
457 |
|
* figure out how many more photons we have to emit from |
473 |
|
srcPhotonFlux = srcFlux [srcIdx] / srcNumEmit; |
474 |
|
avgPhotonFlux = photonFluxSum / (srcIdx + 1); |
475 |
|
|
476 |
< |
if (avgPhotonFlux > 0 && |
476 |
> |
if (avgPhotonFlux > FTINY && |
477 |
|
srcPhotonFlux / avgPhotonFlux < FTINY) { |
478 |
|
/* Skip source if its photon flux is grossly below the |
479 |
|
* running average, indicating negligible contributions |
480 |
|
* at the expense of excessive distribution time; only |
481 |
|
* output from subproc 0 to reduce console clutter */ |
482 |
< |
sprintf(errmsg, |
483 |
< |
"source %s: itsy bitsy photon flux, skipped", |
484 |
< |
source [srcIdx].so -> oname); |
485 |
< |
error(WARNING, errmsg); |
486 |
< |
srcNumEmit = 0; |
482 |
> |
if (!proc) { |
483 |
> |
sprintf(errmsg, |
484 |
> |
"source %s: itsy bitsy photon flux, skipped", |
485 |
> |
source [srcIdx].so -> oname); |
486 |
> |
error(WARNING, errmsg); |
487 |
> |
} |
488 |
> |
|
489 |
> |
srcNumEmit = 0; /* Or just break??? */ |
490 |
|
} |
491 |
|
|
492 |
|
/* Update sum of photon flux per light source */ |
527 |
|
|
528 |
|
for (emap.partitionCnt = 0; emap.partitionCnt < emap.numPartitions; |
529 |
|
emap.partitionCnt++) { |
530 |
+ |
#ifndef PMAP_SIGUSR |
531 |
|
double partNumEmit; |
532 |
|
unsigned long partEmitCnt; |
533 |
+ |
#endif |
534 |
|
|
535 |
|
/* Get photon origin within current source partishunn |
536 |
|
* and build emission map */ |
627 |
|
pm -> numPhotons); |
628 |
|
eputs(errmsg); |
629 |
|
fflush(stderr); |
630 |
+ |
#endif |
631 |
+ |
|
632 |
+ |
#ifdef PMAP_SIGUSR |
633 |
+ |
signal(SIGUSR1, SIG_DFL); |
634 |
|
#endif |
635 |
|
|
636 |
|
#if NIX |