Garfield++ 5.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
neBEMInterface.h File Reference
#include <stdio.h>
#include <time.h>
#include "Vector.h"

Go to the source code of this file.

Macros

#define INTFACEGLOBAL   extern
 
#define neBEMtwopi   6.283185307179586476925287
 
#define neBEMrtod   57.2957795
 
#define MODULUS(p)
 

Functions

INTFACEGLOBAL double neBEMTimeElapsed (clock_t, clock_t)
 
INTFACEGLOBAL int neBEMMessage (const char *message)
 
INTFACEGLOBAL int neBEMGetNbOfLines (const char *fname)
 
INTFACEGLOBAL double neBEMChkInPoly (int nvert, Point3D node[], Point3D pt)
 
INTFACEGLOBAL int neBEMSetDefaults (void)
 
INTFACEGLOBAL int ReadInitFile (char filename[])
 
INTFACEGLOBAL int neBEMGetInputsFromFiles (void)
 
INTFACEGLOBAL int neBEMInitialize (void)
 
INTFACEGLOBAL int neBEMReadGeometry (void)
 
INTFACEGLOBAL int neBEMGetNbPrimitives (void)
 
INTFACEGLOBAL int neBEMGetPrimitive (int prim, int *nvertex, double xvert[], double yvert[], double zvert[], double *xnorm, double *ynorm, double *znorm, int *volref1, int *volref2)
 
INTFACEGLOBAL int neBEMVolumeDescription (int ivol, int *shape, int *material, double *epsilon, double *potential, double *charge, int *boundarytype)
 
INTFACEGLOBAL int neBEMVolumePoint (double x, double y, double z)
 
INTFACEGLOBAL void neBEMVolumePrimitives (int volume, int *nprim, int primlist[])
 
INTFACEGLOBAL int neBEMGetPeriodicities (int prim, int *ix, int *jx, double *sx, int *iy, int *jy, double *sy, int *iz, int *jz, double *sz)
 
INTFACEGLOBAL int neBEMGetMirror (int prim, int *ix, int *jx, double *sx, int *iy, int *jy, double *sy, int *iz, int *jz, double *sz)
 
INTFACEGLOBAL int neBEMGetBoundingPlanes (int *ixmin, double *cxmin, double *vxmin, int *ixmax, double *cxmax, double *vxmax, int *iymin, double *cymin, double *vymin, int *iymax, double *cymax, double *vymax, int *izmin, double *czmin, double *vzmin, int *izmax, double *czmax, double *vzmax)
 
INTFACEGLOBAL int neBEMDiscretize (int **elementNbs)
 
INTFACEGLOBAL int neBEMBoundaryInitialConditions (void)
 
INTFACEGLOBAL int neBEMSolve (void)
 
INTFACEGLOBAL int neBEMPF (Point3D *, double *, Vector3D *)
 
INTFACEGLOBAL double neBEMVolumeCharge (int volume)
 
INTFACEGLOBAL int neBEMPrepareWeightingField (int NbPrimsWtField, int PrimListWtField[])
 
INTFACEGLOBAL void neBEMDeleteWeightingField (int IdWtField)
 
INTFACEGLOBAL void neBEMDeleteAllWeightingFields (void)
 
INTFACEGLOBAL double neBEMWeightingField (Point3D *point, Vector3D *field, int IdWtField)
 
INTFACEGLOBAL int neBEMEnd (void)
 
INTFACEGLOBAL int CreateDirStr (void)
 
INTFACEGLOBAL int WritePrimitives (void)
 
INTFACEGLOBAL int ReadPrimitives (void)
 
INTFACEGLOBAL int WriteElements (void)
 
INTFACEGLOBAL int ReadElements (void)
 

Variables

INTFACEGLOBAL clock_t startClock
 
INTFACEGLOBAL clock_t stopClock
 
INTFACEGLOBAL int neBEMState
 
INTFACEGLOBAL int OptDeviceFile
 
INTFACEGLOBAL char DeviceInputFile [256]
 
INTFACEGLOBAL int NbThreads
 
INTFACEGLOBAL int OptPrintPrimaryDetails
 
INTFACEGLOBAL int OptPrintVolumeDetails
 
INTFACEGLOBAL int OptGnuplot
 
INTFACEGLOBAL int OptGnuplotPrimitives
 
INTFACEGLOBAL int OptGnuplotElements
 
INTFACEGLOBAL FILE * fgnuPrim
 
INTFACEGLOBAL FILE * fgnuElem
 
INTFACEGLOBAL FILE * fgnuMesh
 
INTFACEGLOBAL int OptPrintVertexAndNormal
 
INTFACEGLOBAL int OptPrimitiveFiles
 
INTFACEGLOBAL int OptElementFiles
 
INTFACEGLOBAL int neBEMPFCallCntr
 
INTFACEGLOBAL int OptReuseDir
 

Macro Definition Documentation

◆ INTFACEGLOBAL

◆ MODULUS

#define MODULUS ( p)
Value:
(sqrt(p.X * p.X + p.Y * p.Y + p.Z * p.Z))

Definition at line 35 of file neBEMInterface.h.

Referenced by neBEMChkInPoly().

◆ neBEMrtod

#define neBEMrtod   57.2957795

Definition at line 34 of file neBEMInterface.h.

◆ neBEMtwopi

#define neBEMtwopi   6.283185307179586476925287

Definition at line 33 of file neBEMInterface.h.

Referenced by InitChargingUp(), and neBEMChkInPoly().

Function Documentation

◆ CreateDirStr()

INTFACEGLOBAL int CreateDirStr ( void )

Definition at line 2702 of file neBEMInterface.c.

2702 {
2703 char strModelCntr[10], strMeshCntr[10], strBCCntr[10], strPPCntr[10];
2704 int CreateOrUseDir(char[]);
2705 int CreateDirOrQuit(char[]);
2706
2707 snprintf(strModelCntr, 10, "/Model%d", ModelCntr);
2708 snprintf(strMeshCntr, 10, "/M%d", MeshCntr);
2709 snprintf(strBCCntr, 10, "/BC%d", BCCntr);
2710 snprintf(strPPCntr, 10, "/PP%d", PPCntr);
2711
2712 strcpy(ModelOutDir, DeviceOutDir);
2713 strcat(ModelOutDir, strModelCntr);
2714 strcpy(NativeOutDir, ModelOutDir);
2715 strcat(NativeOutDir, "/neBEMNatives/");
2716 strcpy(NativePrimDir, NativeOutDir);
2717 strcat(NativePrimDir, "Primitives/");
2718 strcpy(MeshOutDir, ModelOutDir);
2719 strcat(MeshOutDir, strMeshCntr);
2720 strcpy(BCOutDir, MeshOutDir);
2721 strcat(BCOutDir, strBCCntr);
2722 strcpy(PPOutDir, BCOutDir);
2723 strcat(PPOutDir, strPPCntr);
2724
2725 // Create DeviceOutDir, if necessary
2726 int fstatus = CreateOrUseDir(DeviceOutDir);
2727 if (fstatus != 0) {
2728 neBEMMessage("CreateDirStr - CreateOrUseDir");
2729 return -1;
2730 }
2731
2732 if (NewModel) {
2733 // create ModelOutDir
2734 if (OptReuseDir) {
2735 fstatus = CreateOrUseDir(ModelOutDir);
2736 fstatus = CreateOrUseDir(NativeOutDir);
2737 fstatus = CreateOrUseDir(NativePrimDir);
2738 } else {
2739 fstatus = CreateDirOrQuit(ModelOutDir);
2740 fstatus = CreateDirOrQuit(NativeOutDir);
2741 fstatus = CreateDirOrQuit(NativePrimDir);
2742 }
2743 if (fstatus != 0) {
2744 neBEMMessage("CreateDirStr - ModelOutDir");
2745 return -1;
2746 }
2747 }
2748
2749 if (NewMesh) {
2750 // create MeshOutDir
2751 if (OptReuseDir)
2752 fstatus = CreateOrUseDir(MeshOutDir);
2753 else
2754 fstatus = CreateDirOrQuit(MeshOutDir);
2755 if (fstatus != 0) {
2756 neBEMMessage("CreateDirStr - MeshOutDir");
2757 return -1;
2758 }
2759 }
2760
2761 if (NewBC) {
2762 // create BCOutDir
2763 if (OptReuseDir)
2764 fstatus = CreateOrUseDir(BCOutDir);
2765 else
2766 fstatus = CreateDirOrQuit(BCOutDir);
2767 if (fstatus != 0) {
2768 neBEMMessage("CreateDirStr - BCOutDir");
2769 return -1;
2770 }
2771 }
2772
2773 if (NewPP) {
2774 // create PPOutDir
2775 if (OptReuseDir)
2776 fstatus = CreateOrUseDir(PPOutDir);
2777 else
2778 fstatus = CreateDirOrQuit(PPOutDir);
2779 if (fstatus != 0) {
2780 neBEMMessage("CreateDirStr - PPOutDir");
2781 return -1;
2782 }
2783 }
2784
2785 // Create other relevant sub-directories
2786 char subdir[256];
2787
2788 strcpy(subdir, ModelOutDir);
2789 strcat(subdir, "/Primitives/");
2790 if (OptReuseDir)
2791 fstatus = CreateOrUseDir(subdir);
2792 else
2793 fstatus = CreateDirOrQuit(subdir);
2794
2795 strcpy(subdir, MeshOutDir);
2796 strcat(subdir, "/Elements/");
2797 if (OptReuseDir)
2798 fstatus = CreateOrUseDir(subdir);
2799 else
2800 fstatus = CreateDirOrQuit(subdir);
2801
2802 strcpy(subdir, MeshOutDir);
2803 strcat(subdir, "/GViewDir/");
2804 if (OptReuseDir)
2805 fstatus = CreateOrUseDir(subdir);
2806 else
2807 fstatus = CreateDirOrQuit(subdir);
2808
2809 return (0);
2810} // CreateDirStr ends
int neBEMMessage(const char *message)
int CreateOrUseDir(char dirname[])
int CreateDirOrQuit(char dirname[])
INTFACEGLOBAL int OptReuseDir
neBEMGLOBAL int MeshCntr
Definition neBEM.h:184
neBEMGLOBAL int PPCntr
Definition neBEM.h:184
neBEMGLOBAL char MeshOutDir[256]
Definition neBEM.h:223
neBEMGLOBAL int NewModel
Definition neBEM.h:180
neBEMGLOBAL char PPOutDir[256]
Definition neBEM.h:223
neBEMGLOBAL int NewMesh
Definition neBEM.h:180
neBEMGLOBAL char ModelOutDir[256]
Definition neBEM.h:222
neBEMGLOBAL int NewPP
Definition neBEM.h:180
neBEMGLOBAL char NativeOutDir[256]
Definition neBEM.h:222
neBEMGLOBAL int BCCntr
Definition neBEM.h:184
neBEMGLOBAL int ModelCntr
Definition neBEM.h:184
neBEMGLOBAL char NativePrimDir[256]
Definition neBEM.h:223
neBEMGLOBAL char DeviceOutDir[256]
Definition neBEM.h:222
neBEMGLOBAL char BCOutDir[256]
Definition neBEM.h:223
neBEMGLOBAL int NewBC
Definition neBEM.h:180

Referenced by neBEMInitialize().

◆ neBEMBoundaryInitialConditions()

INTFACEGLOBAL int neBEMBoundaryInitialConditions ( void )

Definition at line 1756 of file neBEMInterface.c.

1756 {
1757 startClock = clock();
1758
1759 // The boundary conditions can be set only with neBEMState == 4 or 7
1760 // This state is assigned either after element discretization has been
1761 // completed or in a condition when we are looking for modifying only the
1762 // boundary condition for a device having same geometry (hence, the same
1763 // inverted influence coefficient matrix)
1764 if ((neBEMState == 4) || (neBEMState == 7)) {
1765 int fstatus = BoundaryConditions();
1766 if (fstatus != 0) {
1767 neBEMMessage("neBEMBondaryInitialConditions - BoundaryConditions");
1768 return -1;
1769 }
1770 fstatus = InitialConditions();
1771 if (fstatus != 0) {
1772 neBEMMessage("neBEMBondaryInitialConditions - InitialConditions");
1773 return -1;
1774 }
1775 if (neBEMState == 4) neBEMState = 5; // create LHMatrix, invert etc
1776 if (neBEMState == 7) neBEMState = 8; // assume LHS and inversion to be over
1777 } else {
1778 printf("Boundary & initial conditions can be set in states 4 / 7 ...\n");
1779 printf("returning ...\n");
1780 return (-1);
1781 }
1782
1783 stopClock = clock();
1785 printf("to setup boundary and initial conditions.\n");
1786
1787 return (0);
1788} // neBEMBoundaryInitialConditions ends
double neBEMTimeElapsed(clock_t t0, clock_t t1)
INTFACEGLOBAL clock_t stopClock
INTFACEGLOBAL int neBEMState
INTFACEGLOBAL clock_t startClock
neBEMGLOBAL int BoundaryConditions(void)
Definition ReTriM.c:2125
neBEMGLOBAL int InitialConditions(void)
Definition ReTriM.c:2153

◆ neBEMChkInPoly()

INTFACEGLOBAL double neBEMChkInPoly ( int nvert,
Point3D node[],
Point3D pt )

◆ neBEMDeleteAllWeightingFields()

INTFACEGLOBAL void neBEMDeleteAllWeightingFields ( void )

Definition at line 2593 of file neBEMInterface.c.

2593 {
2594 const int MaxWtField = MAXWtFld; // being used while allocating memory
2595 for (int id = 1; id < MaxWtField; ++id) { // count from 1
2596 free(WtFieldChDen[id]);
2597 free(AvWtChDen[id]);
2598 }
2599 free(WtFieldChDen);
2600 free(AvWtChDen);
2601}
#define MAXWtFld
Definition neBEM.h:30
neBEMGLOBAL double ** AvWtChDen
Definition neBEM.h:346
neBEMGLOBAL double ** WtFieldChDen
Definition neBEM.h:346

◆ neBEMDeleteWeightingField()

INTFACEGLOBAL void neBEMDeleteWeightingField ( int IdWtField)

Definition at line 2587 of file neBEMInterface.c.

2587 {
2588 free(WtFieldChDen[IdWtField]);
2589 free(AvWtChDen[IdWtField]);
2590}

◆ neBEMDiscretize()

INTFACEGLOBAL int neBEMDiscretize ( int ** elementNbs)

Definition at line 1454 of file neBEMInterface.c.

1454 {
1455 // int fstatus;
1456
1457 // For a model and a mesh that were defined before and for which data were
1458 // stored in two files - one for primitives and one for elements
1459 // The following operation does not assume that the primitives have been read
1460 // in from a stored file. In essence, these two read-in-s are maintained
1461 // independent of each other. However, for a stored element file to be useful,
1462 // both the model and mesh have to be old (not new).
1463 if ((!NewModel) && (!NewMesh) && (!NewBC) && (OptStoreElements)) {
1464 int fstatus = ReadElements();
1465 if (fstatus) {
1466 neBEMMessage("neBEMDiscretize - problem reading stored Elements.\n");
1467 return -1;
1468 }
1469 neBEMState = 4;
1470 return 0;
1471 }
1472
1473 // Otherwise, continue with fresh discretization
1474 if (neBEMState != 3) {
1475 printf("discretization can continue only in State 3 ...\n");
1476 return -1;
1477 }
1478
1479 // Only the number of primitives has been ascertained.
1480 // All the rest globally important numbers will be determined in this function
1481 NbSurfs = 0;
1482 NbWires = 0;
1483 NbElements = 0;
1484
1485 // Here, the primitive can be analyzed and the elements necessary to
1486 // discretize it, may be determined. A user hint may help that can be supplied
1487 // during the setting up of the device. The hint may be as naive as gross,
1488 // coarse, medium, regular, fine depending on which the element size (in %
1489 // of the device / primitive) may be decided upon.
1490 // Earlier method of specifying the number of primitives on a priori has been
1491 // over-ridden.
1492 // Now we prescribe the length / area of each element and discretize each
1493 // primitive such that each element has an length / area close to the
1494 // suggested value.
1495 // Since the number of elements are being decided here, all the shapes will
1496 // have to be one among wire, right triangle and restangle. Any decomposition
1497 // of arbitrary polygons into rectangles (as many as possible) and right
1498 // triangles will have to be done earlier. All the counts have been
1499 // incremented by one to be on the safe side! The additional memory can be
1500 // minimized through a more careful computation of the required allocation for
1501 // each type of primitive.
1502 char MeshLogFile[256];
1503
1504 strcpy(MeshLogFile, MeshOutDir);
1505 strcat(MeshLogFile, "/MeshLog.out");
1506 fMeshLog = fopen(MeshLogFile, "w");
1507 fprintf(fMeshLog, "Details of primitive discretization\n");
1508
1509 for (int prim = 1; prim <= NbPrimitives; ++prim) {
1510 if (NbVertices[prim] == 4) {
1511 NbSurfSegX[prim] = NbElemsOnPrimitives[prim][1];
1512 NbSurfSegZ[prim] = NbElemsOnPrimitives[prim][2];
1513 int fstatus =
1514 AnalyzePrimitive(prim, &NbSurfSegX[prim], &NbSurfSegZ[prim]);
1515 if (fstatus == 0) {
1516 neBEMMessage("neBEMDiscretize - AnalyzePrimitve");
1517 return -1;
1518 }
1519 NbElements += (NbSurfSegX[prim] + 1) * (NbSurfSegZ[prim] + 1);
1520 }
1521 if (NbVertices[prim] == 3) {
1522 NbSurfSegX[prim] = NbElemsOnPrimitives[prim][1];
1523 NbSurfSegZ[prim] = NbElemsOnPrimitives[prim][2];
1524 int fstatus =
1525 AnalyzePrimitive(prim, &NbSurfSegX[prim], &NbSurfSegZ[prim]);
1526 if (fstatus == 0) {
1527 neBEMMessage("neBEMDiscretize - AnalyzePrimitive");
1528 return -1;
1529 }
1530 NbElements += (NbSurfSegX[prim] + 1) * (NbSurfSegZ[prim] + 1);
1531 }
1532 if (NbVertices[prim] == 2) {
1533 int itmp;
1534 NbWireSeg[prim] = NbElemsOnPrimitives[prim][1];
1535 int fstatus = AnalyzePrimitive(prim, &NbWireSeg[prim], &itmp);
1536 if (fstatus == 0) {
1537 neBEMMessage("neBEMDiscretize - AnalyzePrimitive");
1538 return -1;
1539 }
1540 NbElements += (NbWireSeg[prim] + 1);
1541 }
1542 if (DebugLevel == 101) {
1543 if (NbVertices[prim] == 2) {
1544 printf("Primitive %d to be discretized into %d elements.\n", prim,
1545 NbWireSeg[prim]);
1546 } else {
1547 printf("Primitive %d to be discretized into %d X %d elements.\n", prim,
1548 NbSurfSegX[prim], NbSurfSegZ[prim]);
1549 }
1550 }
1551 }
1552 printf("Memory allocated for maximum %d elements.\n", NbElements);
1553 fclose(fMeshLog);
1554
1555 // Allocate enough space to store all the elements
1556 if (neBEMState == 3) {
1557 printf("neBEMDiscretize: NbElements = %d, sizeof(Element) = %zu\n",
1558 NbElements, sizeof(Element));
1559 if (EleArr) {
1560 Element *tmp = (Element *)realloc(EleArr, NbElements * sizeof(Element));
1561 if (tmp != NULL) {
1562 EleArr = tmp;
1563 EleCntr = 0;
1564 } else {
1565 free(EleArr);
1566 printf("neBEMDiscretize: Re-allocating EleArr failed.\n");
1567 return (1);
1568 }
1569 printf("neBEMDiscretize: Re-allocated EleArr.\n");
1570 } // if EleArr => re-allocation
1571 else {
1572 EleArr = (Element *)malloc(NbElements * sizeof(Element));
1573 if (EleArr == NULL) {
1574 neBEMMessage("neBEMDiscretize - EleArr malloc");
1575 return -1;
1576 }
1577 } // else EleArr => fresh allocation
1578 } // neBEMState == 3
1579
1580 // Prepare a data file that will contain the plotting information of the
1581 // the primitives and the elements
1582 if (OptGnuplot) {
1583 char GnuFile[256];
1584 strcpy(GnuFile, MeshOutDir);
1585 strcat(GnuFile, "/GViewDir/gPrimView.gp");
1586 fgnuPrim = fopen(GnuFile, "w");
1587 fprintf(fgnuPrim, "set title \"neBEM primitives in gnuplot VIEWER\"\n");
1588 // fprintf(fgnu, "#set label 1 \'LengthScale = %d\', LengthScale, right\n");
1589 fprintf(fgnuPrim, "#set pm3d\n");
1590 fprintf(fgnuPrim, "#set style data pm3d\n");
1591 fprintf(fgnuPrim, "#set palette model CMY\n");
1592 fprintf(fgnuPrim, "set hidden3d\n");
1593 fprintf(fgnuPrim, "set nokey\n");
1594 fprintf(fgnuPrim, "set xlabel \"X\"\n");
1595 fprintf(fgnuPrim, "set ylabel \"Y\"\n");
1596 fprintf(fgnuPrim, "set zlabel \"Z\"\n");
1597 fprintf(fgnuPrim, "set view 70, 335, 1, 1\n");
1598 fprintf(fgnuPrim, "\nsplot \\\n");
1599
1600 strcpy(GnuFile, MeshOutDir);
1601 strcat(GnuFile, "/GViewDir/gElemView.gp");
1602 fgnuElem = fopen(GnuFile, "w");
1603 fprintf(fgnuElem, "set title \"neBEM elements in gnuplot VIEWER\"\n");
1604 // fprintf(fgnu, "#set label 1 \'LengthScale = %d\', LengthScale, right\n");
1605 fprintf(fgnuElem, "#set pm3d\n");
1606 fprintf(fgnuElem, "#set style data pm3d\n");
1607 fprintf(fgnuElem, "#set palette model CMY\n");
1608 fprintf(fgnuElem, "set hidden3d\n");
1609 fprintf(fgnuElem, "set nokey\n");
1610 fprintf(fgnuElem, "set xlabel \"X\"\n");
1611 fprintf(fgnuElem, "set ylabel \"Y\"\n");
1612 fprintf(fgnuElem, "set zlabel \"Z\"\n");
1613 fprintf(fgnuElem, "set view 70, 335, 1, 1\n");
1614 fprintf(fgnuElem, "\nsplot \\\n");
1615
1616 strcpy(GnuFile, MeshOutDir);
1617 strcat(GnuFile, "/GViewDir/gMeshView.gp");
1618 fgnuMesh = fopen(GnuFile, "w");
1619 fprintf(fgnuMesh, "set title \"neBEM mesh in gnuplot VIEWER\"\n");
1620 // fprintf(fgnu, "#set label 1 \'LengthScale = %d\', LengthScale, right\n");
1621 fprintf(fgnuMesh, "#set pm3d\n");
1622 fprintf(fgnuMesh, "#set style data pm3d\n");
1623 fprintf(fgnuMesh, "#set palette model CMY\n");
1624 fprintf(fgnuMesh, "set hidden3d\n");
1625 fprintf(fgnuMesh, "set nokey\n");
1626 fprintf(fgnuMesh, "set xlabel \"X\"\n");
1627 fprintf(fgnuMesh, "set ylabel \"Y\"\n");
1628 fprintf(fgnuMesh, "set zlabel \"Z\"\n");
1629 fprintf(fgnuMesh, "set view 70, 335, 1, 1\n");
1630 fprintf(fgnuMesh, "\nsplot \\\n");
1631 }
1632
1633 for (int prim = 1; prim <= NbPrimitives; ++prim) {
1634 switch (PrimType[prim]) {
1635 int fstatus;
1636 case 3: // triangular surface
1637 case 4: // rectangular surface
1638 ++NbSurfs;
1639 fstatus = SurfaceElements(
1640 prim, NbVertices[prim], XVertex[prim], YVertex[prim], ZVertex[prim],
1641 XNorm[prim], YNorm[prim], ZNorm[prim], VolRef1[prim], VolRef2[prim],
1642 InterfaceType[prim], ApplPot[prim], ApplCh[prim], Lambda[prim],
1643 NbSurfSegX[prim], NbSurfSegZ[prim]);
1644 if (fstatus != 0) {
1645 neBEMMessage("neBEMDiscretize - SurfaceElements");
1646 return -1;
1647 }
1648 break;
1649 case 2: // wire - a wire presumably has only 2 vertices
1650 ++NbWires; // it has one radius and one segmentation information
1651 fstatus = WireElements(
1652 prim, NbVertices[prim], XVertex[prim], YVertex[prim], ZVertex[prim],
1653 Radius[prim], VolRef1[prim], VolRef2[prim], InterfaceType[prim],
1654 ApplPot[prim], ApplCh[prim], Lambda[prim], NbWireSeg[prim]);
1655 if (fstatus != 0) {
1656 neBEMMessage("neBEMDiscretize - WireElements");
1657 return -1;
1658 }
1659 break;
1660
1661 default:
1662 printf("PrimType out of range in CreateElements ... exiting ...\n");
1663 exit(-1);
1664 } // switch PrimType ends
1665 } // loop on prim number ends
1666
1667 if (OptGnuplot) {
1668 fprintf(fgnuPrim, "\n\npause-1");
1669 fclose(fgnuPrim);
1670 fprintf(fgnuElem, "\n\npause-1");
1671 fclose(fgnuElem);
1672 fprintf(fgnuMesh, "\n\npause-1");
1673 fclose(fgnuMesh);
1674 }
1675
1676 // If the required memory exceeds the maximum allowed number of elements
1677 if (EleCntr > NbElements) {
1678 neBEMMessage("neBEMDiscretize - EleCntr more than NbElements!");
1679 return -1;
1680 }
1681
1682 // Check whether collocation points overlap
1683 {
1684 int startcntr = 1, cntr1, cntr2;
1685 Point3D pt1, pt2;
1686 double dist;
1687 for (cntr1 = startcntr; cntr1 <= EleCntr; ++cntr1) {
1688 pt1.X = (EleArr + cntr1 - 1)->BC.CollPt.X;
1689 pt1.Y = (EleArr + cntr1 - 1)->BC.CollPt.Y;
1690 pt1.Z = (EleArr + cntr1 - 1)->BC.CollPt.Z;
1691 for (cntr2 = cntr1 + 1; cntr2 <= EleCntr; ++cntr2) {
1692 pt2.X = (EleArr + cntr2 - 1)->BC.CollPt.X;
1693 pt2.Y = (EleArr + cntr2 - 1)->BC.CollPt.Y;
1694 pt2.Z = (EleArr + cntr2 - 1)->BC.CollPt.Z;
1695
1696 dist = GetDistancePoint3D(&pt1, &pt2);
1697 if (dist <= MINDIST) {
1698 // we need a linked-list here so that the overlapped
1699 // element is easily deleted and the rest upgraded immediately
1700
1701 // Upgrade the element array manually, starting from cntr2 and restart
1702 // the overlap check. At present it is only a warning to the user with
1703 // some relevant information.
1704 // Find the primitives and volumes for the overlapping elements
1705 // The element structure should also maintain information on the
1706 // volumes that an element belongs to.
1707 int prim1 = (EleArr + cntr1 - 1)->PrimitiveNb;
1708 int volele1 = VolRef1[prim1];
1709 int prim2 = (EleArr + cntr2 - 1)->PrimitiveNb;
1710 int volele2 = VolRef1[prim2];
1711
1712 neBEMMessage("neBEMDiscretize - Overlapping collocation points!");
1713 printf("Element %d, primitive %d, volume %d overlaps with\n", cntr1,
1714 prim1, volele1);
1715 printf("\telement %d, primitive %d, volume %d.\n", cntr2, prim2,
1716 volele2);
1717 printf("\tposition 1: (%g , %g , %g) micron,\n", 1e6 * pt1.X,
1718 1e6 * pt1.Y, 1e6 * pt1.Z);
1719 printf("\tposition 2: (%g , %g , %g) micron.\n", 1e6 * pt2.X,
1720 1e6 * pt2.Y, 1e6 * pt2.Z);
1721 printf("Please redo the geometry.\n");
1722 return -1;
1723 } // if dist <= MINDIST
1724 } // for cntr2
1725 } // for cntr1
1726 } // check collocation point overlap
1727
1728 NbElements = EleCntr; // the final number of elements
1729 printf("Total final number of elements: %d\n", NbElements);
1730
1731 // Store element related data in a file for a new mesh created, if opted for
1732 if (NewMesh && OptStoreElements) {
1733 if (OptFormattedFile) {
1734 int fstatus = WriteElements();
1735 if (fstatus) {
1736 neBEMMessage("neBEMDiscretize - problem writing Elements.\n");
1737 return -1;
1738 }
1739 } // formatted file
1740
1741 if (OptUnformattedFile) {
1743 "neBEMDiscretize - unformatted write not inplemented yet.\n");
1744 return -1;
1745 } // unformatted file
1746 } // store elements
1747
1748 neBEMState = 4;
1749 stopClock = clock();
1751 printf("to complete discretization\n");
1752
1753 return (0);
1754} // neBEMDiscretize ends
#define MINDIST
Definition Isles.h:18
double GetDistancePoint3D(Point3D *a, Point3D *b)
Definition Vector.c:192
int ReadElements(void)
int WriteElements(void)
INTFACEGLOBAL FILE * fgnuPrim
INTFACEGLOBAL FILE * fgnuElem
INTFACEGLOBAL FILE * fgnuMesh
INTFACEGLOBAL int OptGnuplot
neBEMGLOBAL Element * EleArr
Definition neBEM.h:176
neBEMGLOBAL double * ApplPot
Definition neBEM.h:82
neBEMGLOBAL int DebugLevel
Definition neBEM.h:195
neBEMGLOBAL int EleCntr
Definition neBEM.h:119
neBEMGLOBAL double * ZNorm
Definition neBEM.h:78
neBEMGLOBAL double ** ZVertex
Definition neBEM.h:78
neBEMGLOBAL int * NbWireSeg
Definition neBEM.h:106
neBEMGLOBAL int * NbSurfSegX
Definition neBEM.h:105
neBEMGLOBAL int OptFormattedFile
Definition neBEM.h:56
neBEMGLOBAL double * XNorm
Definition neBEM.h:78
neBEMGLOBAL int NbPrimitives
Definition neBEM.h:64
neBEMGLOBAL int * NbVertices
Definition neBEM.h:77
neBEMGLOBAL int WireElements(int prim, int nvertex, double xvert[], double yvert[], double zvert[], double radius, int volref1, int volref2, int inttype, double potential, double charge, double lambda, int NbWireSeg)
Definition ReTriM.c:82
neBEMGLOBAL int AnalyzePrimitive(int, int *, int *)
Definition ReTriM.c:121
neBEMGLOBAL int NbElements
Definition neBEM.h:120
neBEMGLOBAL double * Lambda
Definition neBEM.h:82
neBEMGLOBAL double ** YVertex
Definition neBEM.h:78
neBEMGLOBAL int * NbSurfSegZ
Definition neBEM.h:105
neBEMGLOBAL int NbWires
Definition neBEM.h:104
neBEMGLOBAL int * VolRef1
Definition neBEM.h:83
neBEMGLOBAL double * YNorm
Definition neBEM.h:78
neBEMGLOBAL double ** XVertex
Definition neBEM.h:78
neBEMGLOBAL int * VolRef2
Definition neBEM.h:83
neBEMGLOBAL int NbSurfs
Definition neBEM.h:104
neBEMGLOBAL double * Radius
Definition neBEM.h:79
neBEMGLOBAL int * InterfaceType
Definition neBEM.h:75
neBEMGLOBAL int * PrimType
Definition neBEM.h:74
neBEMGLOBAL int OptUnformattedFile
Definition neBEM.h:57
neBEMGLOBAL FILE * fMeshLog
Definition neBEM.h:121
neBEMGLOBAL int SurfaceElements(int prim, int nvertex, double xvert[], double yvert[], double zvert[], double xnorm, double ynorm, double znorm, int volref1, int volref2, int inttype, double potential, double charge, double lambda, int NbSegX, int NbSegZ)
Definition ReTriM.c:33
neBEMGLOBAL int OptStoreElements
Definition neBEM.h:54
neBEMGLOBAL double * ApplCh
Definition neBEM.h:82
double X
Definition Vector.h:22
double Z
Definition Vector.h:24
double Y
Definition Vector.h:23

◆ neBEMEnd()

INTFACEGLOBAL int neBEMEnd ( void )

Definition at line 2684 of file neBEMInterface.c.

2684 {
2685 fprintf(fIsles,
2686 "IslesCntr: %d, ExactCntr: %d, FailureCntr: %d, ApproxCntr: %d\n",
2688 fclose(fIsles);
2689 fIsles = NULL;
2690 printf("neBEM ends ... bye!\n");
2691
2692 return 0;
2693} // neBEMEnd ends
ISLESGLOBAL int ApproxCntr
Definition Isles.h:35
ISLESGLOBAL int IslesCntr
Definition Isles.h:35
ISLESGLOBAL FILE * fIsles
Definition Isles.h:37
ISLESGLOBAL int FailureCntr
Definition Isles.h:35
ISLESGLOBAL int ExactCntr
Definition Isles.h:35

◆ neBEMGetBoundingPlanes()

INTFACEGLOBAL int neBEMGetBoundingPlanes ( int * ixmin,
double * cxmin,
double * vxmin,
int * ixmax,
double * cxmax,
double * vxmax,
int * iymin,
double * cymin,
double * vymin,
int * iymax,
double * cymax,
double * vymax,
int * izmin,
double * czmin,
double * vzmin,
int * izmax,
double * czmax,
double * vzmax )

◆ neBEMGetInputsFromFiles()

INTFACEGLOBAL int neBEMGetInputsFromFiles ( void )

◆ neBEMGetMirror()

INTFACEGLOBAL int neBEMGetMirror ( int prim,
int * ix,
int * jx,
double * sx,
int * iy,
int * jy,
double * sy,
int * iz,
int * jz,
double * sz )

◆ neBEMGetNbOfLines()

INTFACEGLOBAL int neBEMGetNbOfLines ( const char * fname)

◆ neBEMGetNbPrimitives()

INTFACEGLOBAL int neBEMGetNbPrimitives ( void )

◆ neBEMGetPeriodicities()

INTFACEGLOBAL int neBEMGetPeriodicities ( int prim,
int * ix,
int * jx,
double * sx,
int * iy,
int * jy,
double * sy,
int * iz,
int * jz,
double * sz )

◆ neBEMGetPrimitive()

INTFACEGLOBAL int neBEMGetPrimitive ( int prim,
int * nvertex,
double xvert[],
double yvert[],
double zvert[],
double * xnorm,
double * ynorm,
double * znorm,
int * volref1,
int * volref2 )

◆ neBEMInitialize()

INTFACEGLOBAL int neBEMInitialize ( void )

Definition at line 39 of file neBEMInterface.c.

39 {
40 // Version information
41 strcpy(neBEMVersion, "1.9.09");
42 strcpy(ISLESVersion, "1.4.9");
43 printf("Using neBEM version %s and ISLES version %s\n", neBEMVersion,
45
46 // The following is not an absolute necessity, but can ease the burden of the
47 // user by setting default values of some of the important variable. Please
48 // take a look at the src/Interface/ExampleDev2neBEM.c to find out what values
49 // are being set, and what they mean.
50 int fstatus = neBEMSetDefaults();
51 if (fstatus != 0) {
52 neBEMMessage("neBEMInitialize - neBEMSetDefaults");
53 return -1;
54 }
55
56 // Change some of the global variables according to requirements.
57 // Note that the solution flags and counters are set before the neBEMSolve
58 // is invoked.
59 LengthScale = 1.0;
60 DebugLevel = 0;
61
62 // The following function allows input files to be read and the geometry
63 // set according to these files, as was customary in the previous versions
64 if (OptDeviceFile) {
65 printf("Reading geometry details from %s\n", DeviceInputFile);
66 fstatus = neBEMGetInputsFromFiles();
67 if (fstatus != 0) {
68 neBEMMessage("neBEMInitialize - neBEMGetInputFromFiles");
69 return -1;
70 }
71 }
72
73 // creation of the mother output directory should be necessary only once
74 if (neBEMState == 0) {
75 fstatus = CreateDirStr();
76 if (fstatus != 0) {
77 neBEMMessage("neBEMInitialize - CreateDirStr");
78 return -1;
79 }
80 }
81
82 // Create Isles log file for keeping track of approximations (numerical
83 // quadrature) in case evaluation of algebraic expressions fails.
84 char IslesFile[256];
85 strcpy(IslesFile, PPOutDir);
86 strcat(IslesFile, "/Isles.log");
87 fIsles = fopen(IslesFile, "w");
88 if (fIsles == NULL) {
89 neBEMMessage("neBEMInitialize - IslesFile");
90 return -1;
91 }
92
93 // following integers keep track of the success / failure of the exact
94 // expressions in estimating realistic physical properties.
96
97 // Set up parameters related to neBEM computations
98 // The file will be removed soon
99#ifdef _OPENMP
100 int RqstdThreads = 1;
101 if (NbThreads > 0) RqstdThreads = NbThreads;
102#endif
103 /*
104 FILE *processFile = fopen("neBEMInp/neBEMProcess.inp", "r");
105 if (processFile == NULL) {
106 printf("neBEMProcess.inp absent ... assuming defaults ...\n");
107 PrimAfter = 0;
108 if (NbThreads > 0) RqstdThreads = NbThreads;
109 } else {
110 fscanf(processFile, "PrimAfter: %d\n", &PrimAfter);
111 fscanf(processFile, "RqstdThreads: %d\n", &RqstdThreads);
112 fclose(processFile);
113 }
114 */
115 // PrimAfter is assigned a value through "SetPrimAfter" member function of
116 // ComponentNeBem3d class.
117 // Default value of PrimAfter is a negative integer.
118
119#ifdef _OPENMP
120 int MaxProcessors = omp_get_num_procs();
121 if (RqstdThreads > 1) {
122 if (RqstdThreads < MaxProcessors) {
123 // one processor left alone
124 omp_set_num_threads(RqstdThreads);
125 } else {
126 printf("RqstdThreads: %d\n", RqstdThreads);
127 RqstdThreads = MaxProcessors - 1;
128 omp_set_num_threads(RqstdThreads);
129 printf("Adjusted RqstdThreads: %d\n", RqstdThreads);
130 }
131 } else {
132 // Work with one thread
133 RqstdThreads = 1; // cannot be zero or negative!
134 omp_set_num_threads(RqstdThreads);
135 printf("RqstdThreads: %d => No Multi-threading ...\n", RqstdThreads);
136 }
137
138 // OpenMP related information
139 printf("PrimAfter: %d\n", PrimAfter);
140 printf("RqstdThreads: %d, MaxProcessors: %d\n", RqstdThreads, MaxProcessors);
141 printf("Maximum number of threads to be used for parallelization: %d\n",
142 omp_get_max_threads());
143 printf("Number of threads used for neBEMInitialize: %d\n",
144 omp_get_num_threads());
145#endif
146
147 // Set up parameters related to voxelized data export for Garfield++
148 // To be removed soon
149 FILE *voxelInpFile = fopen("neBEMInp/neBEMVoxel.inp", "r");
150 if (voxelInpFile == NULL) {
151 printf("neBEMVoxel.inp absent ... assuming OptVoxel = 0 ...\n");
152 OptVoxel = 0;
153 OptStaggerVoxel = 0;
154 } else {
155 fscanf(voxelInpFile, "OptVoxel: %d\n", &OptVoxel);
156 fscanf(voxelInpFile, "OptStaggerVoxel: %d\n", &OptStaggerVoxel);
157 fscanf(voxelInpFile, "Xmin: %le\n", &Voxel.Xmin);
158 fscanf(voxelInpFile, "Xmax: %le\n", &Voxel.Xmax);
159 fscanf(voxelInpFile, "Ymin: %le\n", &Voxel.Ymin);
160 fscanf(voxelInpFile, "Ymax: %le\n", &Voxel.Ymax);
161 fscanf(voxelInpFile, "Zmin: %le\n", &Voxel.Zmin);
162 fscanf(voxelInpFile, "Zmax: %le\n", &Voxel.Zmax);
163 fscanf(voxelInpFile, "XStagger: %le\n", &Voxel.XStagger);
164 fscanf(voxelInpFile, "YStagger: %le\n", &Voxel.YStagger);
165 fscanf(voxelInpFile, "ZStagger: %le\n", &Voxel.ZStagger);
166 fscanf(voxelInpFile, "NbOfXCells: %d\n", &Voxel.NbXCells);
167 fscanf(voxelInpFile, "NbOfYCells: %d\n", &Voxel.NbYCells);
168 fscanf(voxelInpFile, "NbOfZCells: %d\n", &Voxel.NbZCells);
169 fclose(voxelInpFile);
170 } // inputs for Voxel
171
172 // Set up parameters related to 3dMap data export for Garfield++
173 // To be removed soon
174 FILE *mapInpFile = fopen("neBEMInp/neBEMMap.inp", "r");
175 if (mapInpFile == NULL) {
176 printf("neBEMMap.inp absent ... assuming OptMap = 0 ...\n");
177 OptMap = 0;
178 OptStaggerMap = 0;
179 } else {
180 // While reading the input, OptMap and OptStaggerMap have to be read
181 // first since that will decide whether there is a map and its version.
182 fscanf(mapInpFile, "OptMap: %d\n", &OptMap);
183 fscanf(mapInpFile, "OptStaggerMap: %d\n", &OptStaggerMap);
184 fscanf(mapInpFile, "MapVersion: %9s\n", MapVersion);
185 fscanf(mapInpFile, "Xmin: %le\n", &Map.Xmin);
186 fscanf(mapInpFile, "Xmax: %le\n", &Map.Xmax);
187 fscanf(mapInpFile, "Ymin: %le\n", &Map.Ymin);
188 fscanf(mapInpFile, "Ymax: %le\n", &Map.Ymax);
189 fscanf(mapInpFile, "Zmin: %le\n", &Map.Zmin);
190 fscanf(mapInpFile, "Zmax: %le\n", &Map.Zmax);
191 fscanf(mapInpFile, "XStagger: %le\n", &Map.XStagger);
192 fscanf(mapInpFile, "YStagger: %le\n", &Map.YStagger);
193 fscanf(mapInpFile, "ZStagger: %le\n", &Map.ZStagger);
194 fscanf(mapInpFile, "NbOfXCells: %d\n", &Map.NbXCells);
195 fscanf(mapInpFile, "NbOfYCells: %d\n", &Map.NbYCells);
196 fscanf(mapInpFile, "NbOfZCells: %d\n", &Map.NbZCells);
197 fclose(mapInpFile);
198 } // inputs for 3dMap
199
200 // Set up parameters related to fast volume
201 if (OptFastVol) {
202 FILE *fastInpFile = fopen("neBEMInp/neBEMFastVol.inp", "r");
203 if (fastInpFile == NULL) {
204 printf("neBEMFastVol.inp absent ... assuming OptFastVol = 0 ...\n");
205 OptFastVol = 0;
207 OptCreateFastPF = 0;
208 OptReadFastPF = 0;
209 FastVol.NbBlocks = 0;
210 FastVol.NbOmitVols = 0;
211 FastVol.NbIgnoreVols = 0;
212 } else {
213 fscanf(fastInpFile, "OptFastVol: %d\n", &OptFastVol);
214 fscanf(fastInpFile, "OptStaggerFastVol: %d\n", &OptStaggerFastVol);
215 fscanf(fastInpFile, "OptCreateFastPF: %d\n", &OptCreateFastPF);
216 fscanf(fastInpFile, "OptReadFastPF: %d\n", &OptReadFastPF);
217 fscanf(fastInpFile, "NbPtSkip: %d\n", &NbPtSkip);
218 fscanf(fastInpFile, "NbStgPtSkip: %d\n", &NbStgPtSkip);
219 fscanf(fastInpFile, "LX: %le\n", &FastVol.LX);
220 fscanf(fastInpFile, "LY: %le\n", &FastVol.LY);
221 fscanf(fastInpFile, "LZ: %le\n", &FastVol.LZ);
222 fscanf(fastInpFile, "CornerX: %le\n", &FastVol.CrnrX);
223 fscanf(fastInpFile, "CornerY: %le\n", &FastVol.CrnrY);
224 fscanf(fastInpFile, "CornerZ: %le\n", &FastVol.CrnrZ);
225 fscanf(fastInpFile, "YStagger: %le\n", &FastVol.YStagger);
227 FastVol.YStagger = 0.0; // ignore any non-zero value
228 fscanf(fastInpFile, "NbOfBlocks: %d\n", &FastVol.NbBlocks);
229 BlkNbXCells = ivector(1, FastVol.NbBlocks);
230 BlkNbYCells = ivector(1, FastVol.NbBlocks);
231 BlkNbZCells = ivector(1, FastVol.NbBlocks);
232 BlkLZ = dvector(1, FastVol.NbBlocks);
233 BlkCrnrZ = dvector(1, FastVol.NbBlocks);
234 for (int block = 1; block <= FastVol.NbBlocks; ++block) {
235 fscanf(fastInpFile, "NbOfXCells: %d\n", &BlkNbXCells[block]);
236 fscanf(fastInpFile, "NbOfYCells: %d\n", &BlkNbYCells[block]);
237 fscanf(fastInpFile, "NbOfZCells: %d\n", &BlkNbZCells[block]);
238 fscanf(fastInpFile, "LZ: %le\n", &BlkLZ[block]);
239 fscanf(fastInpFile, "CornerZ: %le\n", &BlkCrnrZ[block]);
240 } // inputs for blocks
241 fscanf(fastInpFile, "NbOfOmitVols: %d\n", &FastVol.NbOmitVols);
242 if (FastVol.NbOmitVols) {
243 OmitVolLX = dvector(1, FastVol.NbOmitVols);
244 OmitVolLY = dvector(1, FastVol.NbOmitVols);
245 OmitVolLZ = dvector(1, FastVol.NbOmitVols);
246 OmitVolCrnrX = dvector(1, FastVol.NbOmitVols);
247 OmitVolCrnrY = dvector(1, FastVol.NbOmitVols);
248 OmitVolCrnrZ = dvector(1, FastVol.NbOmitVols);
249 for (int omit = 1; omit <= FastVol.NbOmitVols; ++omit) {
250 fscanf(fastInpFile, "OmitVolLX: %le\n", &OmitVolLX[omit]);
251 fscanf(fastInpFile, "OmitVolLY: %le\n", &OmitVolLY[omit]);
252 fscanf(fastInpFile, "OmitVolLZ: %le\n", &OmitVolLZ[omit]);
253 fscanf(fastInpFile, "OmitVolCornerX: %le\n", &OmitVolCrnrX[omit]);
254 fscanf(fastInpFile, "OmitVolCornerY: %le\n", &OmitVolCrnrY[omit]);
255 fscanf(fastInpFile, "OmitVolCornerZ: %le\n", &OmitVolCrnrZ[omit]);
256 } // inputs for OmitVols
257 } // inputs for OmitVols
258 fscanf(fastInpFile, "NbOfIgnoreVols: %d\n", &FastVol.NbIgnoreVols);
259 if (FastVol.NbIgnoreVols) {
260 IgnoreVolLX = dvector(1, FastVol.NbIgnoreVols);
261 IgnoreVolLY = dvector(1, FastVol.NbIgnoreVols);
262 IgnoreVolLZ = dvector(1, FastVol.NbIgnoreVols);
263 IgnoreVolCrnrX = dvector(1, FastVol.NbIgnoreVols);
264 IgnoreVolCrnrY = dvector(1, FastVol.NbIgnoreVols);
265 IgnoreVolCrnrZ = dvector(1, FastVol.NbIgnoreVols);
266 for (int ignore = 1; ignore <= FastVol.NbIgnoreVols; ++ignore) {
267 fscanf(fastInpFile, "IgnoreVolLX: %le\n", &IgnoreVolLX[ignore]);
268 fscanf(fastInpFile, "IgnoreVolLY: %le\n", &IgnoreVolLY[ignore]);
269 fscanf(fastInpFile, "IgnoreVolLZ: %le\n", &IgnoreVolLZ[ignore]);
270 fscanf(fastInpFile, "IgnoreVolCornerX: %le\n",
271 &IgnoreVolCrnrX[ignore]);
272 fscanf(fastInpFile, "IgnoreVolCornerY: %le\n",
273 &IgnoreVolCrnrY[ignore]);
274 fscanf(fastInpFile, "IgnoreVolCornerZ: %le\n",
275 &IgnoreVolCrnrZ[ignore]);
276 } // inputs for IgnoreVols
277 } // inputs for IgnoreVols
278 for (int ignore = 1; ignore <= FastVol.NbIgnoreVols; ++ignore) {
279 printf("IgnoreVolLX: %le\n", IgnoreVolLX[ignore]);
280 printf("IgnoreVolLY: %le\n", IgnoreVolLY[ignore]);
281 printf("IgnoreVolLZ: %le\n", IgnoreVolLZ[ignore]);
282 printf("IgnoreVolCornerX: %le\n", IgnoreVolCrnrX[ignore]);
283 printf("IgnoreVolCornerY: %le\n", IgnoreVolCrnrY[ignore]);
284 printf("IgnoreVolCornerZ: %le\n", IgnoreVolCrnrZ[ignore]);
285 } // inputs for IgnoreVols
286 fclose(fastInpFile);
287 } // else fastInpFile
288 } // if OptFastVol
289
290 printf("neBEM initialized ...\n");
291 fflush(stdout);
292 sleep(3); // wait for three seconds so that the user gets time to react
293
294 neBEMState = 1; // state 1 implied initialization of neBEM completed
295
296 // announce success - later, add the name of the calling code
297 return (0);
298} // neBEMInitialize ends
ISLESGLOBAL char ISLESVersion[10]
Definition Isles.h:31
int CreateDirStr(void)
INTFACEGLOBAL int NbThreads
INTFACEGLOBAL char DeviceInputFile[256]
INTFACEGLOBAL int neBEMGetInputsFromFiles(void)
INTFACEGLOBAL int OptDeviceFile
INTFACEGLOBAL int neBEMSetDefaults(void)
neBEMGLOBAL int OptStaggerFastVol
Definition neBEM.h:419
neBEMGLOBAL int OptVoxel
Definition neBEM.h:368
neBEMGLOBAL double * OmitVolCrnrZ
Definition neBEM.h:451
neBEMGLOBAL MapVol Map
Definition neBEM.h:410
neBEMGLOBAL double * OmitVolLX
Definition neBEM.h:446
neBEMGLOBAL int OptStaggerMap
Definition neBEM.h:393
neBEMGLOBAL char neBEMVersion[10]
Definition neBEM.h:36
neBEMGLOBAL double * BlkCrnrZ
Definition neBEM.h:445
neBEMGLOBAL int OptCreateFastPF
Definition neBEM.h:420
neBEMGLOBAL FastAlgoVol FastVol
Definition neBEM.h:439
neBEMGLOBAL int PrimAfter
Definition neBEM.h:364
neBEMGLOBAL double * BlkLZ
Definition neBEM.h:444
neBEMGLOBAL double * OmitVolCrnrX
Definition neBEM.h:449
neBEMGLOBAL double * OmitVolLZ
Definition neBEM.h:448
neBEMGLOBAL int NbStgPtSkip
Definition neBEM.h:425
neBEMGLOBAL double * IgnoreVolCrnrY
Definition neBEM.h:456
neBEMGLOBAL char MapVersion[10]
Definition neBEM.h:394
neBEMGLOBAL int NbPtSkip
Definition neBEM.h:424
neBEMGLOBAL int OptMap
Definition neBEM.h:392
neBEMGLOBAL double * OmitVolCrnrY
Definition neBEM.h:450
neBEMGLOBAL int OptFastVol
Definition neBEM.h:418
neBEMGLOBAL double * OmitVolLY
Definition neBEM.h:447
neBEMGLOBAL int * BlkNbXCells
Definition neBEM.h:441
neBEMGLOBAL int OptReadFastPF
Definition neBEM.h:421
neBEMGLOBAL int * BlkNbZCells
Definition neBEM.h:443
neBEMGLOBAL double * IgnoreVolLY
Definition neBEM.h:453
neBEMGLOBAL double * IgnoreVolLX
Definition neBEM.h:452
neBEMGLOBAL double LengthScale
Definition neBEM.h:198
neBEMGLOBAL double * IgnoreVolLZ
Definition neBEM.h:454
neBEMGLOBAL VoxelVol Voxel
Definition neBEM.h:385
neBEMGLOBAL double * IgnoreVolCrnrX
Definition neBEM.h:455
neBEMGLOBAL double * IgnoreVolCrnrZ
Definition neBEM.h:457
neBEMGLOBAL int * BlkNbYCells
Definition neBEM.h:442
neBEMGLOBAL int OptStaggerVoxel
Definition neBEM.h:369
int * ivector(long nl, long nh)
Definition nrutil.c:33
double * dvector(long nl, long nh)
Definition nrutil.c:64

◆ neBEMMessage()

◆ neBEMPF()

INTFACEGLOBAL int neBEMPF ( Point3D * point,
double * potential,
Vector3D * field )

Definition at line 2096 of file neBEMInterface.c.

2096 {
2097 if (neBEMState < 9) {
2098 printf("neBEMPF cannot be called before reaching state 9.\n");
2099 return (-1);
2100 }
2101
2102 // printf("neBEMPF called %8d times", ++neBEMPFCallCntr);
2103
2104 double Pot;
2105 int fstatus;
2106 if (OptFastVol) // Note: this is not the Create or Read option
2107 {
2108 fstatus = FastPFAtPoint(point, &Pot, field);
2109 if (fstatus != 0) {
2110 neBEMMessage("neBEMPF - FastPFAtPoint");
2111 return -1;
2112 }
2113 } else {
2114 fstatus = PFAtPoint(point, &Pot, field);
2115 if (fstatus != 0) {
2116 neBEMMessage("neBEMPF - PFAtPoint");
2117 return -1;
2118 }
2119 }
2120
2121 *potential = Pot;
2122
2123 // printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
2124
2125 return (0);
2126} // neBEMPF ends
int FastPFAtPoint(Point3D *globalP, double *Potential, Vector3D *globalF)
int PFAtPoint(Point3D *globalP, double *Potential, Vector3D *globalF)

◆ neBEMPrepareWeightingField()

INTFACEGLOBAL int neBEMPrepareWeightingField ( int NbPrimsWtField,
int PrimListWtField[] )

Definition at line 2141 of file neBEMInterface.c.

2141 {
2142 static int IdWtField = 0;
2143
2144 int dbgFn = 0;
2145 int fstatus = 0;
2146
2147 if (neBEMState < 7) {
2148 printf(
2149 "neBEMPrepareWeightingField: Weighting computations only meaningful "
2150 "beyond neBEMState 7 ...\n");
2151 return -1;
2152 }
2153
2154 // Find first free slot
2155 const int MaxWtField =
2156 MAXWtFld; // used also while deallocating these memories
2157 if (WtFieldChDen == NULL)
2158 WtFieldChDen = (double **)malloc(MaxWtField * sizeof(double *));
2159 if (AvWtChDen == NULL)
2160 AvWtChDen = (double **)malloc(MaxWtField * sizeof(double *));
2161
2162 ++IdWtField;
2163 if (IdWtField >= MaxWtField) {
2164 printf(
2165 "neBEMPrepareWeightingField: reached MaxWtField (%d) weighting "
2166 "fields.\n",
2167 MAXWtFld);
2168 return -1;
2169 } else {
2170 printf("\nPreparing weighting field for %d-th set.\n", IdWtField);
2171 } // else within MaxWtField
2172
2173 // Allocate a new column to store this solution set
2174 WtFieldChDen[IdWtField] = (double *)malloc((NbElements + 2) * sizeof(double));
2175 AvWtChDen[IdWtField] = (double *)malloc((NbPrimitives + 2) * sizeof(double));
2176
2177 fstatus = WeightingFieldSolution(nprim, primlist, WtFieldChDen[IdWtField]);
2178 if (fstatus) {
2179 neBEMMessage("neBEMPrepareWeightingField - WeightingFieldSolution");
2180 return -1;
2181 } else {
2182 printf("Computed weighting field solution\n");
2183 }
2184
2185 // estimate primitive related avrg wt field charge densities
2186 // OMPCheck - may be parallelized
2187 for (int prim = 1; prim <= NbPrimitives; ++prim) {
2188 double area = 0.0; // need area of the primitive as well!
2189 AvWtChDen[IdWtField][prim] = 0.0;
2190
2191 for (int ele = ElementBgn[prim]; ele <= ElementEnd[prim]; ++ele) {
2192 area += (EleArr + ele - 1)->G.dA;
2193 AvWtChDen[IdWtField][prim] +=
2194 WtFieldChDen[IdWtField][ele] * (EleArr + ele - 1)->G.dA;
2195 }
2196
2197 AvWtChDen[IdWtField][prim] /= area;
2198 }
2199 printf("Computed primitive-averaged weighting field solutions\n");
2200
2201 // stringify the integer
2202 char strIdWtField[5];
2203 snprintf(strIdWtField, 5, "%d", IdWtField);
2204 // printf("strIdWtField: %s\n", strIdWtField);
2205
2206 // Set up parameters related to fixed specification of weighting field
2207 // printf("OptFixedWtField: %d\n", OptFixedWtField[IdWtField]);fflush(stdout);
2208 if (OptFixedWtField[IdWtField]) {
2209 char fileWtField[256];
2210 strcpy(fileWtField, "neBEMInp/neBEMFixedWtField_");
2211 strcat(fileWtField, strIdWtField);
2212 strcat(fileWtField, ".inp");
2213 FILE *fixedWtInpFile = fopen(fileWtField, "r");
2214 if (fixedWtInpFile == NULL) {
2215 printf(
2216 "neBEMFixedWtField.inp absent ... assuming OptFixedWtField = 0 "
2217 "...\n");
2218 OptFixedWtField[IdWtField] = 0;
2219 FixedWtPotential[IdWtField] = 0.0;
2220 FixedWtFieldX[IdWtField] = 0.0;
2221 FixedWtFieldY[IdWtField] = 0.0;
2222 FixedWtFieldZ[IdWtField] = 0.0;
2223 } else {
2224 fscanf(fixedWtInpFile, "OptFixedWtField: %d\n",
2225 &OptFixedWtField[IdWtField]);
2226 fscanf(fixedWtInpFile, "FixedWtPotential: %lg\n",
2227 &FixedWtPotential[IdWtField]);
2228 fscanf(fixedWtInpFile, "FixedWtFieldX: %lg\n", &FixedWtFieldX[IdWtField]);
2229 fscanf(fixedWtInpFile, "FixedWtFieldY: %lg\n", &FixedWtFieldY[IdWtField]);
2230 fscanf(fixedWtInpFile, "FixedWtFieldZ: %lg\n", &FixedWtFieldZ[IdWtField]);
2231 fclose(fixedWtInpFile);
2232 } // else fixedWtInpFile
2233 } // if OptFixedWtField
2234
2235 // Weighting field fast volume related computations
2236 // Set up parameters related to weighting field fast volumes.
2237 // There can be multiple weighting fields depending on readout electrodes.
2238 // As a result, there can be multiple versions of this input file, each
2239 // reflecting the requirement of one set of electrodes.
2240 // printf("OptWtFldFastVol: %d\n", OptWtFldFastVol[IdWtField]);fflush(stdout);
2241 if (OptWtFldFastVol[IdWtField]) {
2242 char fileWtField[256];
2243 strcpy(fileWtField, "neBEMInp/neBEMWtFldFastVol_");
2244 strcat(fileWtField, strIdWtField);
2245 strcat(fileWtField, ".inp");
2246 FILE *fastWtFldInpFile = fopen(fileWtField, "r");
2247 // FILE *fastWtFldInpFile = fopen("neBEMInp/neBEMWtFldFastVol.inp", "r");
2248 if (fastWtFldInpFile == NULL) {
2249 printf(
2250 "neBEMWtFldFastVol.inp absent ... assuming OptWtFldFastVol = 0 "
2251 "...\n");
2252 OptWtFldFastVol[IdWtField] = 0;
2253 OptStaggerWtFldFastVol[IdWtField] = 0;
2254 OptCreateWtFldFastPF[IdWtField] = 0;
2255 OptReadWtFldFastPF[IdWtField] = 0;
2256 WtFldFastVol[IdWtField].NbBlocks = 0;
2257 WtFldFastVol[IdWtField].NbOmitVols = 0;
2258 WtFldFastVol[IdWtField].NbIgnoreVols = 0;
2259 } else {
2260 fscanf(fastWtFldInpFile, "OptFastVol: %d\n", &OptWtFldFastVol[IdWtField]);
2261 fscanf(fastWtFldInpFile, "OptStaggerFastVol: %d\n",
2262 &OptStaggerWtFldFastVol[IdWtField]);
2263 fscanf(fastWtFldInpFile, "OptCreateFastPF: %d\n",
2264 &OptCreateWtFldFastPF[IdWtField]);
2265 fscanf(fastWtFldInpFile, "OptReadFastPF: %d\n",
2266 &OptReadWtFldFastPF[IdWtField]);
2267 fscanf(fastWtFldInpFile, "NbPtSkip: %d\n", &WtFldNbPtSkip[IdWtField]);
2268 fscanf(fastWtFldInpFile, "NbStgPtSkip: %d\n",
2269 &StgWtFldNbPtSkip[IdWtField]);
2270 fscanf(fastWtFldInpFile, "LX: %le\n", &WtFldFastVol[IdWtField].LX);
2271 fscanf(fastWtFldInpFile, "LY: %le\n", &WtFldFastVol[IdWtField].LY);
2272 fscanf(fastWtFldInpFile, "LZ: %le\n", &WtFldFastVol[IdWtField].LZ);
2273 fscanf(fastWtFldInpFile, "CornerX: %le\n",
2274 &WtFldFastVol[IdWtField].CrnrX);
2275 fscanf(fastWtFldInpFile, "CornerY: %le\n",
2276 &WtFldFastVol[IdWtField].CrnrY);
2277 fscanf(fastWtFldInpFile, "CornerZ: %le\n",
2278 &WtFldFastVol[IdWtField].CrnrZ);
2279 fscanf(fastWtFldInpFile, "YStagger: %le\n",
2280 &WtFldFastVol[IdWtField].YStagger);
2281 if (!OptStaggerWtFldFastVol[IdWtField])
2282 WtFldFastVol[IdWtField].YStagger = 0.0; // ignore any non-zero value
2283 fscanf(fastWtFldInpFile, "NbOfBlocks: %d\n",
2284 &WtFldFastVol[IdWtField].NbBlocks);
2285 WtFldBlkNbXCells[IdWtField] =
2286 ivector(1, WtFldFastVol[IdWtField].NbBlocks);
2287 WtFldBlkNbYCells[IdWtField] =
2288 ivector(1, WtFldFastVol[IdWtField].NbBlocks);
2289 WtFldBlkNbZCells[IdWtField] =
2290 ivector(1, WtFldFastVol[IdWtField].NbBlocks);
2291 WtFldBlkLZ[IdWtField] = dvector(1, WtFldFastVol[IdWtField].NbBlocks);
2292 WtFldBlkCrnrZ[IdWtField] = dvector(1, WtFldFastVol[IdWtField].NbBlocks);
2293 for (int block = 1; block <= WtFldFastVol[IdWtField].NbBlocks; ++block) {
2294 fscanf(fastWtFldInpFile, "NbOfXCells: %d\n",
2295 &WtFldBlkNbXCells[IdWtField][block]);
2296 fscanf(fastWtFldInpFile, "NbOfYCells: %d\n",
2297 &WtFldBlkNbYCells[IdWtField][block]);
2298 fscanf(fastWtFldInpFile, "NbOfZCells: %d\n",
2299 &WtFldBlkNbZCells[IdWtField][block]);
2300 fscanf(fastWtFldInpFile, "LZ: %le\n", &WtFldBlkLZ[IdWtField][block]);
2301 fscanf(fastWtFldInpFile, "CornerZ: %le\n",
2302 &WtFldBlkCrnrZ[IdWtField][block]);
2303 } // inputs for blocks
2304 fscanf(fastWtFldInpFile, "NbOfOmitVols: %d\n",
2305 &WtFldFastVol[IdWtField].NbOmitVols);
2306 if (WtFldFastVol[IdWtField].NbOmitVols) {
2307 WtFldOmitVolLX[IdWtField] =
2308 dvector(1, WtFldFastVol[IdWtField].NbOmitVols);
2309 WtFldOmitVolLY[IdWtField] =
2310 dvector(1, WtFldFastVol[IdWtField].NbOmitVols);
2311 WtFldOmitVolLZ[IdWtField] =
2312 dvector(1, WtFldFastVol[IdWtField].NbOmitVols);
2313 WtFldOmitVolCrnrX[IdWtField] =
2314 dvector(1, WtFldFastVol[IdWtField].NbOmitVols);
2315 WtFldOmitVolCrnrY[IdWtField] =
2316 dvector(1, WtFldFastVol[IdWtField].NbOmitVols);
2317 WtFldOmitVolCrnrZ[IdWtField] =
2318 dvector(1, WtFldFastVol[IdWtField].NbOmitVols);
2319 for (int omit = 1; omit <= WtFldFastVol[IdWtField].NbOmitVols; ++omit) {
2320 fscanf(fastWtFldInpFile, "OmitVolLX: %le\n",
2321 &WtFldOmitVolLX[IdWtField][omit]);
2322 fscanf(fastWtFldInpFile, "OmitVolLY: %le\n",
2323 &WtFldOmitVolLY[IdWtField][omit]);
2324 fscanf(fastWtFldInpFile, "OmitVolLZ: %le\n",
2325 &WtFldOmitVolLZ[IdWtField][omit]);
2326 fscanf(fastWtFldInpFile, "OmitVolCornerX: %le\n",
2327 &WtFldOmitVolCrnrX[IdWtField][omit]);
2328 fscanf(fastWtFldInpFile, "OmitVolCornerY: %le\n",
2329 &WtFldOmitVolCrnrY[IdWtField][omit]);
2330 fscanf(fastWtFldInpFile, "OmitVolCornerZ: %le\n",
2331 &WtFldOmitVolCrnrZ[IdWtField][omit]);
2332 } // for loop inputs for OmitVols
2333 } // inputs for OmitVols
2334 fscanf(fastWtFldInpFile, "NbOfIgnoreVols: %d\n",
2335 &WtFldFastVol[IdWtField].NbIgnoreVols);
2336 if (WtFldFastVol[IdWtField].NbIgnoreVols) {
2337 WtFldIgnoreVolLX[IdWtField] =
2338 dvector(1, WtFldFastVol[IdWtField].NbIgnoreVols);
2339 WtFldIgnoreVolLY[IdWtField] =
2340 dvector(1, WtFldFastVol[IdWtField].NbIgnoreVols);
2341 WtFldIgnoreVolLZ[IdWtField] =
2342 dvector(1, WtFldFastVol[IdWtField].NbIgnoreVols);
2343 WtFldIgnoreVolCrnrX[IdWtField] =
2344 dvector(1, WtFldFastVol[IdWtField].NbIgnoreVols);
2345 WtFldIgnoreVolCrnrY[IdWtField] =
2346 dvector(1, WtFldFastVol[IdWtField].NbIgnoreVols);
2347 WtFldIgnoreVolCrnrZ[IdWtField] =
2348 dvector(1, WtFldFastVol[IdWtField].NbIgnoreVols);
2349 for (int ignore = 1; ignore <= WtFldFastVol[IdWtField].NbIgnoreVols;
2350 ++ignore) {
2351 fscanf(fastWtFldInpFile, "IgnoreVolLX: %le\n",
2352 &WtFldIgnoreVolLX[IdWtField][ignore]);
2353 fscanf(fastWtFldInpFile, "IgnoreVolLY: %le\n",
2354 &WtFldIgnoreVolLY[IdWtField][ignore]);
2355 fscanf(fastWtFldInpFile, "IgnoreVolLZ: %le\n",
2356 &WtFldIgnoreVolLZ[IdWtField][ignore]);
2357 fscanf(fastWtFldInpFile, "IgnoreVolCornerX: %le\n",
2358 &WtFldIgnoreVolCrnrX[IdWtField][ignore]);
2359 fscanf(fastWtFldInpFile, "IgnoreVolCornerY: %le\n",
2360 &WtFldIgnoreVolCrnrY[IdWtField][ignore]);
2361 fscanf(fastWtFldInpFile, "IgnoreVolCornerZ: %le\n",
2362 &WtFldIgnoreVolCrnrZ[IdWtField][ignore]);
2363 } // for loop inputs for IgnoreVols
2364 } // inputs for IgnoreVols
2365 if (dbgFn) {
2366 for (int ignore = 1; ignore <= WtFldFastVol[IdWtField].NbIgnoreVols;
2367 ++ignore) {
2368 printf("WtFldIgnoreVolLX: %le\n",
2369 WtFldIgnoreVolLX[IdWtField][ignore]);
2370 printf("WtFldIgnoreVolLY: %le\n",
2371 WtFldIgnoreVolLY[IdWtField][ignore]);
2372 printf("WtFldIgnoreVolLZ: %le\n",
2373 WtFldIgnoreVolLZ[IdWtField][ignore]);
2374 printf("WtFldIgnoreVolCornerX: %le\n",
2375 WtFldIgnoreVolCrnrX[IdWtField][ignore]);
2376 printf("WtFldIgnoreVolCornerY: %le\n",
2377 WtFldIgnoreVolCrnrY[IdWtField][ignore]);
2378 printf("WtFldIgnoreVolCornerZ: %le\n",
2379 WtFldIgnoreVolCrnrZ[IdWtField][ignore]);
2380 } // inputs for IgnoreVols
2381 }
2382 fclose(fastWtFldInpFile);
2383 } // else fastWtFldInpFile
2384
2385 int MaxXCells = WtFldBlkNbXCells[IdWtField][1];
2386 int MaxYCells = WtFldBlkNbYCells[IdWtField][1];
2387 int MaxZCells = WtFldBlkNbZCells[IdWtField][1];
2388 clock_t startFastClock = clock();
2389
2390 // find maximum number of Xcells etc in all the blocks
2391 // simplifies memory allocation using nrutils but hogs memory!
2392 for (int block = 1; block <= WtFldFastVol[IdWtField].NbBlocks; ++block) {
2393 if (block == 1) {
2394 MaxXCells = WtFldBlkNbXCells[IdWtField][1];
2395 MaxYCells = WtFldBlkNbYCells[IdWtField][1];
2396 MaxZCells = WtFldBlkNbZCells[IdWtField][1];
2397 } else {
2398 if (MaxXCells < WtFldBlkNbXCells[IdWtField][block])
2399 MaxXCells = WtFldBlkNbXCells[IdWtField][block];
2400 if (MaxYCells < WtFldBlkNbYCells[IdWtField][block])
2401 MaxYCells = WtFldBlkNbYCells[IdWtField][block];
2402 if (MaxZCells < WtFldBlkNbZCells[IdWtField][block])
2403 MaxZCells = WtFldBlkNbZCells[IdWtField][block];
2404 }
2405 } // loop block for finding maxm cells among all the blocks
2406
2407 if (dbgFn) {
2408 printf("OptWtFldFastVol: %d\n", OptWtFldFastVol[IdWtField]);
2409 printf("OptStaggerWtFldFastVol: %d\n", OptStaggerWtFldFastVol[IdWtField]);
2410 printf("OptCreateWtFldFastPF: %d\n", OptCreateWtFldFastPF[IdWtField]);
2411 printf("OptReadWtFldFastPF: %d\n", OptReadWtFldFastPF[IdWtField]);
2412 printf("WtFldNbPtSkip: %d\n", WtFldNbPtSkip[IdWtField]);
2413 printf("StgWtFldNbPtSkip: %d\n", StgWtFldNbPtSkip[IdWtField]);
2414 printf("LX: %le\n", WtFldFastVol[IdWtField].LX);
2415 printf("LY: %le\n", WtFldFastVol[IdWtField].LY);
2416 printf("LZ: %le\n", WtFldFastVol[IdWtField].LZ);
2417 printf("CornerX: %le\n", WtFldFastVol[IdWtField].CrnrX);
2418 printf("CornerY: %le\n", WtFldFastVol[IdWtField].CrnrY);
2419 printf("CornerZ: %le\n", WtFldFastVol[IdWtField].CrnrZ);
2420 printf("YStagger: %le\n", WtFldFastVol[IdWtField].YStagger);
2421 printf("NbOfBlocks: %d\n", WtFldFastVol[IdWtField].NbBlocks);
2422 for (int block = 1; block <= WtFldFastVol[IdWtField].NbBlocks; ++block) {
2423 printf("NbOfXCells[%d]: %d\n", block,
2424 WtFldBlkNbXCells[IdWtField][block]);
2425 printf("NbOfYCells[%d]: %d\n", block,
2426 WtFldBlkNbYCells[IdWtField][block]);
2427 printf("NbOfZCells[%d]: %d\n", block,
2428 WtFldBlkNbZCells[IdWtField][block]);
2429 printf("LZ[%d]: %le\n", block, WtFldBlkLZ[IdWtField][block]);
2430 printf("CornerZ[%d]: %le\n", block, WtFldBlkCrnrZ[IdWtField][block]);
2431 }
2432 printf("NbOfOmitVols: %d\n", WtFldFastVol[IdWtField].NbOmitVols);
2433 if (WtFldFastVol[IdWtField].NbOmitVols) {
2434 for (int omit = 1; omit <= WtFldFastVol[IdWtField].NbOmitVols; ++omit) {
2435 printf("OmitVolLX[%d]: %le\n", omit, WtFldOmitVolLX[IdWtField][omit]);
2436 printf("OmitVolLY[%d]: %le\n", omit, WtFldOmitVolLY[IdWtField][omit]);
2437 printf("OmitVolLZ[%d]: %le\n", omit, WtFldOmitVolLZ[IdWtField][omit]);
2438 printf("OmitCrnrX[%d]: %le\n", omit,
2439 WtFldOmitVolCrnrX[IdWtField][omit]);
2440 printf("OmitCrnrY[%d]: %le\n", omit,
2441 WtFldOmitVolCrnrY[IdWtField][omit]);
2442 printf("OmitCrnrZ[%d]: %le\n", omit,
2443 WtFldOmitVolCrnrZ[IdWtField][omit]);
2444 }
2445 }
2446 printf("MaxXCells, MaxYCells, MaxZCells: %d, %d, %d\n", MaxXCells,
2447 MaxYCells, MaxZCells);
2448 printf("NbOfIgnoreVols: %d\n", WtFldFastVol[IdWtField].NbIgnoreVols);
2449 } // dbgFn
2450
2451 // Following memory allocations are necessary even for creating
2452 // the fast volumes.
2453 // In fact, since these tensors are already in place, the fast volumes
2454 // can be used to evaluate potential and fields immediately after they are
2455 // created.
2456 /* Memory wastage!!! Improve as soon as possible. */
2457 WtFldFastPot[IdWtField] =
2458 d4tensor(1, WtFldFastVol[IdWtField].NbBlocks, 1, MaxXCells + 1, 1,
2459 MaxYCells + 1, 1, MaxZCells + 1);
2460 WtFldFastFX[IdWtField] =
2461 d4tensor(1, WtFldFastVol[IdWtField].NbBlocks, 1, MaxXCells + 1, 1,
2462 MaxYCells + 1, 1, MaxZCells + 1);
2463 WtFldFastFY[IdWtField] =
2464 d4tensor(1, WtFldFastVol[IdWtField].NbBlocks, 1, MaxXCells + 1, 1,
2465 MaxYCells + 1, 1, MaxZCells + 1);
2466 WtFldFastFZ[IdWtField] =
2467 d4tensor(1, WtFldFastVol[IdWtField].NbBlocks, 1, MaxXCells + 1, 1,
2468 MaxYCells + 1, 1, MaxZCells + 1);
2469
2470 if (OptStaggerWtFldFastVol[IdWtField]) {
2471 /* Memory wastage!!! Improve as soon as possible. */
2472 StgWtFldFastPot[IdWtField] =
2473 d4tensor(1, WtFldFastVol[IdWtField].NbBlocks, 1, MaxXCells + 1, 1,
2474 MaxYCells + 1, 1, MaxZCells + 1);
2475 StgWtFldFastFX[IdWtField] =
2476 d4tensor(1, WtFldFastVol[IdWtField].NbBlocks, 1, MaxXCells + 1, 1,
2477 MaxYCells + 1, 1, MaxZCells + 1);
2478 StgWtFldFastFY[IdWtField] =
2479 d4tensor(1, WtFldFastVol[IdWtField].NbBlocks, 1, MaxXCells + 1, 1,
2480 MaxYCells + 1, 1, MaxZCells + 1);
2481 StgWtFldFastFZ[IdWtField] =
2482 d4tensor(1, WtFldFastVol[IdWtField].NbBlocks, 1, MaxXCells + 1, 1,
2483 MaxYCells + 1, 1, MaxZCells + 1);
2484 } // if OptStaggerWtFldFastVol
2485
2486 if (OptCreateWtFldFastPF[IdWtField]) {
2487 fstatus = CreateWtFldFastVolPF(IdWtField);
2488
2489 clock_t stopFastClock = clock();
2490 neBEMTimeElapsed(startFastClock, stopFastClock);
2491 printf("to compute WtFldFastVolPF\n");
2492 // neBEMMessage(
2493 // "neBEMSolve - Failure computing WtFldFastVolPF: not implemented");
2494 // return -1;
2495 } // if OptCreateWtFldFastPF
2496
2497 if (OptReadWtFldFastPF[IdWtField]) { // reading from file
2498 int nbXCells, nbYCells, nbZCells;
2499 int tmpblk;
2500 double xpt, ypt, zpt;
2501
2502 // stringify the integer
2503 char stringIdWtField[5];
2504 snprintf(stringIdWtField, 5, "%d", IdWtField);
2505 char FastVolPFFile[256];
2506 strcpy(FastVolPFFile, BCOutDir);
2507 strcat(FastVolPFFile, "/WtFldFastVolPF_");
2508 strcat(FastVolPFFile, stringIdWtField);
2509 strcat(FastVolPFFile, ".out");
2510 FILE *fFastVolPF = fopen(FastVolPFFile, "r");
2511 if (fFastVolPF == NULL) {
2512 neBEMMessage("in neBEMSolve - WtFldFastVolPFFile");
2513 return -1;
2514 }
2515
2516 fscanf(fFastVolPF, "#block\tX\tY\tZ\tPot\tFX\tFY\tFZ\n");
2517
2518 for (int block = 1; block <= WtFldFastVol[IdWtField].NbBlocks; ++block) {
2519 nbXCells = WtFldBlkNbXCells[IdWtField][block];
2520 nbYCells = WtFldBlkNbYCells[IdWtField][block];
2521 nbZCells = WtFldBlkNbZCells[IdWtField][block];
2522
2523 for (int i = 1; i <= nbXCells + 1; ++i) {
2524 for (int j = 1; j <= nbYCells + 1; ++j) {
2525 for (int k = 1; k <= nbZCells + 1; ++k) {
2526 fscanf(fFastVolPF, "%d\t%le\t%le\t%le\t%le\t%le\t%le\t%le\n",
2527 &tmpblk, &xpt, &ypt, &zpt,
2528 &WtFldFastPot[IdWtField][block][i][j][k],
2529 &WtFldFastFX[IdWtField][block][i][j][k],
2530 &WtFldFastFY[IdWtField][block][i][j][k],
2531 &WtFldFastFZ[IdWtField][block][i][j][k]);
2532 } // loop k
2533 } // loop j
2534 } // loop i
2535 } // loop block
2536 fclose(fFastVolPF);
2537
2538 if (OptStaggerWtFldFastVol[IdWtField]) {
2539 // stringify the integer
2540 snprintf(stringIdWtField, 5, "%d", IdWtField);
2541 char StgFastVolPFFile[256];
2542 strcpy(StgFastVolPFFile, BCOutDir);
2543 // strcat(StgFastVolPFFile, "/WtFldStgFastVolPF.out");
2544 strcat(StgFastVolPFFile, "/StgWtFldFastVolPF_");
2545 strcat(StgFastVolPFFile, stringIdWtField);
2546 strcat(StgFastVolPFFile, ".out");
2547 FILE* fStgFastVolPF = fopen(StgFastVolPFFile, "r");
2548 if (fStgFastVolPF == NULL) {
2549 neBEMMessage("in neBEMSolve - StgWtFldFastVolPFFile");
2550 return -1;
2551 }
2552
2553 fscanf(fStgFastVolPF, "#block\tX\tY\tZ\tPot\tFX\tFY\tFZ\n");
2554
2555 for (int block = 1; block <= WtFldFastVol[IdWtField].NbBlocks;
2556 ++block) {
2557 nbXCells = WtFldBlkNbXCells[IdWtField][block];
2558 nbYCells = WtFldBlkNbYCells[IdWtField][block];
2559 nbZCells = WtFldBlkNbZCells[IdWtField][block];
2560
2561 for (int i = 1; i <= nbXCells + 1; ++i) {
2562 for (int j = 1; j <= nbYCells + 1; ++j) {
2563 for (int k = 1; k <= nbZCells + 1; ++k) {
2564 fscanf(fStgFastVolPF, "%d\t%le\t%le\t%le\t%le\t%le\t%le\t%le\n",
2565 &tmpblk, &xpt, &ypt, &zpt,
2566 &StgWtFldFastPot[IdWtField][block][i][j][k],
2567 &StgWtFldFastFX[IdWtField][block][i][j][k],
2568 &StgWtFldFastFY[IdWtField][block][i][j][k],
2569 &StgWtFldFastFZ[IdWtField][block][i][j][k]);
2570 } // loop k
2571 } // loop j
2572 } // loop i
2573 } // loop block
2574 fclose(fStgFastVolPF);
2575 } // if OptStaggerWtFldFastVol
2576
2577 clock_t stopFastClock = clock();
2578 neBEMTimeElapsed(startFastClock, stopFastClock);
2579 printf("to read WtFldFastVolPF\n");
2580 } // if OptReadWtFldFastPF
2581 } // if OptWtFldFastVol
2582
2583 return IdWtField;
2584} // neBEMPrepareWeightingField ends
int CreateWtFldFastVolPF(int IdWtField)
int WeightingFieldSolution(int NbPrimsWtField, int PrimListWtField[], double solnarray[])
Definition neBEM.c:4034
neBEMGLOBAL int WtFldNbPtSkip[MAXWtFld]
Definition neBEM.h:498
neBEMGLOBAL int OptStaggerWtFldFastVol[MAXWtFld]
Definition neBEM.h:493
neBEMGLOBAL double **** StgWtFldFastPot[MAXWtFld]
Definition neBEM.h:537
neBEMGLOBAL double FixedWtFieldZ[MAXWtFld]
Definition neBEM.h:489
neBEMGLOBAL int * WtFldBlkNbZCells[MAXWtFld]
Definition neBEM.h:517
neBEMGLOBAL double * WtFldBlkLZ[MAXWtFld]
Definition neBEM.h:518
neBEMGLOBAL double * WtFldOmitVolCrnrY[MAXWtFld]
Definition neBEM.h:524
neBEMGLOBAL double **** WtFldFastFY[MAXWtFld]
Definition neBEM.h:535
neBEMGLOBAL double * WtFldOmitVolLX[MAXWtFld]
Definition neBEM.h:520
neBEMGLOBAL int OptWtFldFastVol[MAXWtFld]
Definition neBEM.h:492
neBEMGLOBAL int * WtFldBlkNbYCells[MAXWtFld]
Definition neBEM.h:516
neBEMGLOBAL double * WtFldIgnoreVolCrnrZ[MAXWtFld]
Definition neBEM.h:531
neBEMGLOBAL double FixedWtFieldY[MAXWtFld]
Definition neBEM.h:488
neBEMGLOBAL int StgWtFldNbPtSkip[MAXWtFld]
Definition neBEM.h:499
neBEMGLOBAL int OptFixedWtField[MAXWtFld]
Definition neBEM.h:485
neBEMGLOBAL double * WtFldOmitVolCrnrX[MAXWtFld]
Definition neBEM.h:523
neBEMGLOBAL double * WtFldIgnoreVolCrnrY[MAXWtFld]
Definition neBEM.h:530
neBEMGLOBAL double * WtFldBlkCrnrZ[MAXWtFld]
Definition neBEM.h:519
neBEMGLOBAL double * WtFldIgnoreVolCrnrX[MAXWtFld]
Definition neBEM.h:529
neBEMGLOBAL double * WtFldIgnoreVolLY[MAXWtFld]
Definition neBEM.h:527
neBEMGLOBAL int OptCreateWtFldFastPF[MAXWtFld]
Definition neBEM.h:494
neBEMGLOBAL double **** WtFldFastFZ[MAXWtFld]
Definition neBEM.h:536
neBEMGLOBAL int * ElementEnd
Definition neBEM.h:101
neBEMGLOBAL double * WtFldOmitVolCrnrZ[MAXWtFld]
Definition neBEM.h:525
neBEMGLOBAL double * WtFldOmitVolLZ[MAXWtFld]
Definition neBEM.h:522
neBEMGLOBAL double **** StgWtFldFastFX[MAXWtFld]
Definition neBEM.h:538
neBEMGLOBAL int * ElementBgn
Definition neBEM.h:101
neBEMGLOBAL double FixedWtPotential[MAXWtFld]
Definition neBEM.h:486
neBEMGLOBAL int * WtFldBlkNbXCells[MAXWtFld]
Definition neBEM.h:515
neBEMGLOBAL double * WtFldIgnoreVolLZ[MAXWtFld]
Definition neBEM.h:528
neBEMGLOBAL double **** WtFldFastFX[MAXWtFld]
Definition neBEM.h:535
neBEMGLOBAL double * WtFldIgnoreVolLX[MAXWtFld]
Definition neBEM.h:526
neBEMGLOBAL double **** WtFldFastPot[MAXWtFld]
Definition neBEM.h:534
neBEMGLOBAL WtFldFastAlgoVol WtFldFastVol[MAXWtFld]
Definition neBEM.h:513
neBEMGLOBAL double * WtFldOmitVolLY[MAXWtFld]
Definition neBEM.h:521
neBEMGLOBAL double **** StgWtFldFastFY[MAXWtFld]
Definition neBEM.h:538
neBEMGLOBAL double FixedWtFieldX[MAXWtFld]
Definition neBEM.h:487
neBEMGLOBAL int OptReadWtFldFastPF[MAXWtFld]
Definition neBEM.h:495
neBEMGLOBAL double **** StgWtFldFastFZ[MAXWtFld]
Definition neBEM.h:539
double **** d4tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh, long nwl, long nwh)
Definition nrutil.c:261

◆ neBEMReadGeometry()

INTFACEGLOBAL int neBEMReadGeometry ( void )

Definition at line 307 of file neBEMInterface.c.

307 {
308 int dbgFn = 0;
309 int fstatus;
310
311 startClock = clock();
312
313 // For a model that was defined before and for which data was stored in a file
314 if ((!NewModel) && (!NewBC) && (OptStorePrimitives)) {
315 fstatus = ReadPrimitives();
316 if (fstatus) {
317 neBEMMessage("neBEMReadGeometry - problem reading stored Primitives.\n");
318 return -1;
319 }
320 neBEMState = 3; // primitives read in after initialization and Nbs
321 return 0;
322 }
323
324 printf("geometry inputs ...\n");
325 if (neBEMState != 1) {
326 printf("reading geometry possible only after initialization ...\n");
327 return -1;
328 }
329
332 if (NbPrimitives == 0) {
333 // nothing to do - return control to calling routine
334 neBEMMessage("neBEMReadGeometry - no primitive.\n");
335 return (-1); // for the time being
336 }
337
338 NbSurfs = 0;
339 NbWires = 0;
340 neBEMState = 2;
341
342 // Allocate memory for storing the geometry primitives till the elements are
343 // created.
344 // Explicit storage of these variables related to primitives may not be
345 // necessary if the elements are created immediately after a primitive is read
346 // in.
347 // MaxNbVertices = 4; // value specified through SetDefaults or init files
348
349 // neBEM has been initialized, NbPrimitives set
352 OrgnlToEffPrim = imatrix(1, NbPrimitives, 0, 2); // 0 init, 1 intrfc, 2 rmv
361 Radius = dvector(1, NbPrimitives); // can lead to a little memory misuse
365 PrimDC = (DirnCosn3D *)malloc((NbPrimitives + 1) * sizeof(DirnCosn3D));
370 NbWireSeg = ivector(1, NbPrimitives); // little memory misuse
415
416 // Loop over the primitives - major loop
417 int nvertex, volref1, volref2, volmax = 0;
418#ifdef __cplusplus
419 std::vector<double> xvert(MaxNbVertices, 0.);
420 std::vector<double> yvert(MaxNbVertices, 0.);
421 std::vector<double> zvert(MaxNbVertices, 0.);
422#else
423 double xvert[MaxNbVertices], yvert[MaxNbVertices], zvert[MaxNbVertices];
424#endif
425 double xnorm, ynorm, znorm; // in case of wire , radius is read as xnorm
426 for (int prim = 1; prim <= NbPrimitives; ++prim) {
427#ifdef __cplusplus
428 fstatus = neBEMGetPrimitive(prim, &nvertex, xvert.data(), yvert.data(),
429 zvert.data(), &xnorm, &ynorm, &znorm, &volref1,
430 &volref2);
431#else
432 fstatus = neBEMGetPrimitive(prim, &nvertex, xvert, yvert, zvert, // arrays
433 &xnorm, &ynorm, &znorm, &volref1, &volref2);
434#endif
435 if (fstatus != 0) {
436 neBEMMessage("neBEMReadGeometry - neBEMGetPrimitve");
437 return -1;
438 }
439 if (volmax < volref1) {
440 volmax = volref1;
441 } // maxm nb of volumes
442 if (volmax < volref2) {
443 volmax = volref2;
444 } // maxm nb of volumes
445
446 if (nvertex > MaxNbVertices) {
447 printf("Number of vertices for primitive %d exceeds %d!\n", prim,
449 printf("Returning to garfield ...\n");
450 return (-1);
451 }
452
453 PrimType[prim] = nvertex; // wire:2, triangle:3, rectangle:4
454 NbVertices[prim] = nvertex;
455 for (int vert = 0; vert < NbVertices[prim]; ++vert) {
456 XVertex[prim][vert] = xvert[vert];
457 YVertex[prim][vert] = yvert[vert];
458 ZVertex[prim][vert] = zvert[vert];
459 }
460 if (PrimType[prim] == 2) {
461 // wire
462 XNorm[prim] = 0.0; // modulus not 1 - an absurd trio!
463 YNorm[prim] = 0.0;
464 ZNorm[prim] = 0.0;
465 Radius[prim] = xnorm;
466 }
467 if ((PrimType[prim] == 3) || (PrimType[prim] == 4)) {
468 XNorm[prim] = xnorm;
469 YNorm[prim] = ynorm;
470 ZNorm[prim] = znorm;
471 Radius[prim] = 0.0; // absurd radius!
472 }
473 VolRef1[prim] = volref1;
474 VolRef2[prim] = volref2;
475
476 // feedback for user begins - suppress later
478 printf("neBEM:\tprimitive %d between volumes %d, %d has %d vertices\n",
479 prim, volref1, volref2, nvertex);
480 for (int ivertex = 0; ivertex < nvertex; ivertex++) {
481 printf("\tnode %d (%g,%g,%g)\n", ivertex, xvert[ivertex],
482 yvert[ivertex], zvert[ivertex]);
483 }
484 printf("\tnormal vector: (%g,%g,%g)\n", xnorm, ynorm, znorm);
485 }
486 // feedback for user ends - suppress later
487
488 // Now look for the volume related information for this primitve
489 // This is obtained from the specified volume references
490 // volref1 refers to the volume itself
491 // volref2 describes the volume in the direction of the +ve normal
492 // Note that materials from 1 to 10 are conductors and
493 // from 11 to 20
494 // are dielectrics
495 int shape1, material1, boundarytype1;
496 double epsilon1, potential1, charge1;
497 if (volref1 == -1) {
498 // Must be an error, since no device is made of vacuum
499 neBEMMessage("neBEMReadGeometry - volref1 = -1!");
500 return -1;
501 } else {
502 neBEMVolumeDescription(volref1, &shape1, &material1, &epsilon1,
503 &potential1, &charge1, &boundarytype1);
504 }
506 printf("\tvolref1: %d\n", volref1);
507 printf("\t\tboundarytype1: %d, shape1: %d, material1: %d\n",
508 boundarytype1, shape1, material1);
509 printf("\t\tepsilon1: %lg, potential1: %lg, charge1: %lg\n", epsilon1,
510 potential1, charge1);
511 }
512 // in the -ve normal direction - properties of the external volume
513 int shape2, material2, boundarytype2;
514 double epsilon2, potential2, charge2;
515 if (volref2 == -1) {
516 shape2 = 0;
517 material2 = 11;
518 epsilon2 = 1.0;
519 potential2 = 0.0;
520 charge2 = 0.0;
521 boundarytype2 = 0;
522 } else {
523 neBEMVolumeDescription(volref2, &shape2, &material2, &epsilon2,
524 &potential2, &charge2, &boundarytype2);
525 }
527 printf("\tvolref2: %d\n", volref2);
528 printf("\t\tboundarytype2: %d, shape2: %d, material2: %d\n",
529 boundarytype2, shape2, material2);
530 printf("\t\tepsilon2: %lg, potential2: %lg, charge2: %lg\n", epsilon2,
531 potential2, charge2);
532 }
533
534 // Put default values to variables that depend on the interface type
535 // Is there any risk involved in putting these defaults?
536 // At present, they even seem necessary. For example, for floating
537 // conductors or dielectric-dielectric interface, the formulation requires
538 // that the RHS is zero (may be modified by the effect of known charges).
539 Epsilon1[prim] = epsilon1;
540 Epsilon2[prim] = epsilon2; // 1: self, 2: external
541 ApplPot[prim] = 0.0;
542 Lambda[prim] = 0.0;
543 ApplCh[prim] = 0.0;
544
545 // BoundaryTypes:
546 // --------------
547 // Vacuum: 0
548 // Conductor at specified potential: 1
549 // Conductor with a specified charge: 2
550 // Floating conductor (zero charge, perpendicular E): 3
551 // Dielectric intrface (plastic-plastic) without "manual" charge: 4
552 // Dielectric with surface charge (plastic-gas, typically): 5
553 // Symmetry boundary, E parallel: 6 (may not be necessary)
554 // Symmetry boundary, E perpendicular: 7 (may not be necessary)
555
556 // InterfaceType:
557 // --------------
558 // To be skipped: 0
559 // Conductor-dielectric: 1
560 // Conductor with known charge: 2
561 // Conductor at floating potential: 3
562 // Dielectric-dielectric: 4
563 // Dielectric with given surface charge: 5
564 // Check dielectric-dielectric formulation in
565 // (NumSolnOfBIEforMolES_JPBardhan.pdf):
566 // Numerical solution of boundary-integral equations for molecular
567 // electrostatics,
568 // by Jaydeep P. Bardhan,
569 // THE JOURNAL OF CHEMICAL PHYSICS 130, 094102 (2009)
570
571 switch (boundarytype1) { // the volume itself is volref1
572 case 1: // conductor at specified potential
573 if (boundarytype2 == 0 || boundarytype2 == 4) {
574 // dielectric-conductor
575 InterfaceType[prim] = 1;
576 ApplPot[prim] = potential1;
577 } else if (boundarytype2 == 1) {
578 // conductor-conductor
579 if (fabs(potential1 - potential2) // same potential
580 < 1e-6 * (1 + fabs(potential1) + fabs(potential2))) {
581 printf("neBEMReadGeometry: identical potentials; skipped.\n");
582 printf("Primitive skipped: #%d\n", prim);
583 InterfaceType[prim] = 0;
584 } else {
585 // different potentials
586 printf("neBEMReadGeometry: different potentials; rejected.\n");
587 return -1;
588 }
589 } else {
590 // conductor-unknown
591 printf(
592 "neBEMReadGeometry: conductor at given potential; rejected.\n");
593 return -1;
594 }
595 break;
596
597 case 2: // conductor with a specified charge
598 if ((boundarytype2 == 0) || (boundarytype2 == 4)) {
599 // conductor-dielectric
600 InterfaceType[prim] = 2;
601 ApplCh[prim] = charge1;
602 } else {
603 printf("neBEMReadGeometry: charged conductor; rejected.\n");
604 return -1;
605 }
606 break;
607
608 case 3: // floating conductor (zero charge, perpendicular E)
609 if ((boundarytype2 == 0) || (boundarytype2 == 4)) {
610 // conductor-dielectric
611 InterfaceType[prim] = 3;
612 if (!NbFloatingConductors) // assuming only one floating conductor
613 NbFloatingConductors = 1; // in the system
614 } else {
615 printf("neBEMReadGeometry: floating conductor; rejected.\n");
616 return -1;
617 }
618 break;
619
620 case 4: // dielectric interface (plastic-plastic) without "manual" charge
621 if (boundarytype2 == 0) {
622 // dielectric-vacuum
623 // epsilon1 is self dielectric-constant
624 // epsilon2 is towards positive normal
625 InterfaceType[prim] = 4;
626 Lambda[prim] = (epsilon1 - epsilon2) / (epsilon1 + epsilon2);
627 // consistent with Bardhan's eqn 16 where (1 / (2*Lambda)) is used
628 } else if (boundarytype2 == 1) {
629 // dielectric-conductor
630 InterfaceType[prim] = 1; // conductor at known potential
631 ApplPot[prim] = potential2;
632 } else if (boundarytype2 == 2) {
633 // dielectric-conductor
634 InterfaceType[prim] = 2; // conductor with known charge
635 ApplCh[prim] = charge2;
636 } else if (boundarytype2 == 3) {
637 // dielectric-conductor
638 InterfaceType[prim] = 3; // conductor at floating potential
639 } else if (boundarytype2 == 4) {
640 // dielectric-dielectric
641 if (fabs(epsilon1 - epsilon2) <
642 1e-6 * (1 + fabs(epsilon1) + fabs(epsilon2))) {
643 // identical dielectrica
644 printf(
645 "neBEMReadGeometry: between identical dielectrica; skipd.\n");
646 printf("Primitive skipped: #%d\n", prim);
647 InterfaceType[prim] = 0;
648 } else {
649 // distinctly different dielectrica
650 // epsilon1 is self dielectric-constant
651 // epsilon2 towards positive normal
652 InterfaceType[prim] = 4;
653 Lambda[prim] = (epsilon1 - epsilon2) / (epsilon1 + epsilon2);
654 // consistent with Bardhan's paper (1 / Lambda)
655 }
656 } else if (boundarytype2 == 5) {
657 // dielectric-dielectric with charge
658 if (fabs(epsilon1 - epsilon2) // identical dielectrica
659 < 1e-6 * (1 + fabs(epsilon1) + fabs(epsilon2))) {
660 printf(
661 "neBEMReadGeometry: between identical dielectrica; skipped.\n");
662 printf("Primitive skipped: #%d\n", prim);
663 InterfaceType[prim] = 0;
664 } else {
665 // distinctly different dielectrica
666 InterfaceType[prim] = 5; // epsilon2 towards positive normal
667 ApplCh[prim] = charge2;
668 Lambda[prim] = (epsilon1 - epsilon2) / (epsilon1 + epsilon2);
669 }
670 } // if-else if boundarytypes 0 and 4
671 else { // dielectric-unknown
672 printf("neBEMReadGeometry: unknown dielectric; rejected.\n");
673 return -1;
674 }
675 break;
676
677 case 5: // dielectric with surface charge (plastic-gas, typically)
678 if (boundarytype2 == 0) { // dielectric-vacuum
679 InterfaceType[prim] = 5; // epsilon2 is towards +ve normal
680 ApplCh[prim] = charge1;
681 Lambda[prim] = (epsilon1 - epsilon2) / (epsilon1 + epsilon2);
682 // consistent with Bardhan's paper (1 / Lambda)
683 } else if (boundarytype2 == 4) { // dielectric-dielectric
684 if (fabs(epsilon1 - epsilon2) <
685 1e-6 * (1 + fabs(epsilon1) + fabs(epsilon2))) {
686 // identical dielectrica
687 printf(
688 "neBEMReadGeometry: between identical dielectrica; skipd.\n");
689 printf("Primitive skipped: #%d\n", prim);
690 InterfaceType[prim] = 0;
691 } else {
692 // distinctly different dielectrica
693 InterfaceType[prim] = 5; // epsilon2 towards positive normal
694 ApplCh[prim] = charge1;
695 Lambda[prim] = (epsilon1 - epsilon2) / (epsilon1 + epsilon2);
696 // consistent with Bardhan's paper (1 / Lambda)
697 }
698 } // if-else if boundarytypes 0 and 4
699 else {
700 printf(
701 "neBEMReadGeometry: charged dielectric adjacent to a conductor; "
702 "rejected.\n");
703 return -1;
704 }
705 break;
706
707 case 6: // symmetry boundary, E parallel
708 if (boundarytype2 == 0) {
709 InterfaceType[prim] = 6;
710 } else {
711 printf("neBEMReadGeometry: E-parallel symmetry; rejected.\n");
712 return -1;
713 }
714 break;
715
716 case 7: // symmetry boundary, E perpendicular
717 if (boundarytype2 == 0) {
718 InterfaceType[prim] = 7;
719 } else {
720 printf("neBEMReadGeometry: E-perpendicular symmetry; rejected.\n");
721 return -1;
722 }
723 break;
724
725 default:
726 printf("neBEMReadGeometry: Boundary type 1: %d\n", boundarytype1);
727 printf("neBEMReadGeometry: Boundary type 2: %d\n", boundarytype2);
728 printf("neBEMReadGeometry: out of range ... exiting.\n");
729 return -1;
730 } // switch boundarytype1 ends
731
733 printf(
734 "\tType: %d, ApplPot: %lg, Epsilon1: %lg, Epsilon2: %lg, Lambda: "
735 "%lg, ApplCh: %lg\n",
736 InterfaceType[prim], ApplPot[prim], Epsilon1[prim], Epsilon2[prim],
737 Lambda[prim], ApplCh[prim]);
738 }
739
740 // Read the periodicities
741 // Note that mirror has been taken care of separately below
742 // ix: PeriodicTypeX (1 - simple, 2 - mirror, 3 - axial, 4 - rotation)
743 // jx: PeriodicInX (Number of copies internal to neBEM)
744 // sx: XPeriod
745 // NOTE: A change in this part of the algorithm is likely to affect
746 // src/Solve/neBEM.c (LHMatrix) and
747 // src/Solve/ComputeProperties.c (PFAtPoint and WtFldPFAtPoint)
748 {
749 int ix, iy, iz;
750 int jx, jy, jz;
751 double sx, sy, sz;
752 fstatus = neBEMGetPeriodicities(prim, &ix, &jx, &sx, &iy, &jy, &sy, &iz,
753 &jz, &sz);
754 if (fstatus != 0) {
755 neBEMMessage("neBEMReadGeometry - neBEMGetPeriodicities");
756 return -1;
757 }
758 if (jx < 0) jx = 0;
759 if (jy < 0) jy = 0;
760 if (jz < 0) jz = 0;
761
762 PeriodicTypeX[prim] = ix;
763 PeriodicTypeY[prim] = iy;
764 PeriodicTypeZ[prim] = iz;
765 if (0) {
766 printf("For primitive: %d\n", prim);
767 printf("\tPeriodicTypeX: %d, PeriodicTypeY: %d, PeriodicTypeZ: %d\n",
768 ix, iy, iz);
769 printf("\tPeriodicInX: %d, PeriodicInY: %d, PeriodicInZ: %d\n", jx, jy,
770 jz);
771 printf("\tXPeriod: %lg, YPeriod: %lg, ZPeriod: %lg\n", sx, sy, sz);
772 }
773 if (ix > 0) {
774 // These checks need to be done separately. Otherwise, there is
775 // a possibility that non-zero values of PeriodicIn* and *Period
776 // are used throughout the code despite PeriodicType* is 0
777 PeriodicInX[prim] = jx;
778 XPeriod[prim] = sx;
779 } else {
780 PeriodicInX[prim] = 0;
781 XPeriod[prim] = 0.0;
782 }
783 if (iy > 0) {
784 PeriodicInY[prim] = jy;
785 YPeriod[prim] = sy;
786 } else {
787 PeriodicInY[prim] = 0;
788 YPeriod[prim] = 0.0;
789 }
790 if (iz > 0) {
791 PeriodicInZ[prim] = jz;
792 ZPeriod[prim] = sz;
793 } else {
794 PeriodicInZ[prim] = 0;
795 ZPeriod[prim] = 0.0;
796 }
797 } // read periodicity information
798
799 // Read mirror information
800 // Mirror can be in perpendicular to any of the three cartesian axes
801 // There can be more than one mirror at the same time
802 // MirrorType (1 - charge density -ve of original, equivalent to method of
803 // images, 2 - charge density same as original)
804 {
805 int ix, iy, iz;
806 int jx, jy, jz; // not used at present
807 double sx, sy, sz;
808 fstatus =
809 neBEMGetMirror(prim, &ix, &jx, &sx, &iy, &jy, &sy, &iz, &jz, &sz);
810 if (fstatus != 0) {
811 neBEMMessage("neBEMReadGeometry - neBEMGetMirror");
812 return -1;
813 }
814 if (jx < 0) jx = 0;
815 if (jy < 0) jy = 0;
816 if (jz < 0) jz = 0;
817
818 MirrorTypeX[prim] = ix;
819 MirrorTypeY[prim] = iy;
820 MirrorTypeZ[prim] = iz;
821 if (0) {
822 printf("For primitive: %d\n", prim);
823 printf("\tMirrorTypeX: %d, MirrorTypeY: %d, MirrorTypeZ: %d\n", ix, iy,
824 iz);
825 printf("\tNOT USED ==> MirrorInX: %d, MirrorInY: %d, MirrorInZ: %d\n",
826 jx, jy, jz);
827 printf("\tMirrorDistX: %lg, MirrorDistY: %lg, MirrorDistZ: %lg\n", sx,
828 sy, sz);
829 getchar();
830 }
831 if (ix > 0) {
832 // printf("neBEMReadGeometry: Mirror have been requested.\n");
833 MirrorDistXFromOrigin[prim] = sx; // assumed to pass through the origin
834 } else {
835 MirrorDistXFromOrigin[prim] = 0.0; // pass through the origin
836 }
837 if (iy > 0) {
838 // printf("neBEMReadGeometry: Mirror have been requested.\n");
839 MirrorDistYFromOrigin[prim] = sy;
840 } else {
841 MirrorDistYFromOrigin[prim] = 0.0;
842 }
843 if (iz > 0) {
844 // printf("neBEMReadGeometry: Mirror have been requested.\n");
845 MirrorDistZFromOrigin[prim] = sz;
846 } else {
847 MirrorDistZFromOrigin[prim] = 0.0;
848 }
849 } // read mirror information
850
851 // Information on bounding planes
852 // ixmin=0: lower x-plane does not exist
853 // ixmin=1: lower x-plane does exist
854 // cxmin: coordinate of lower x-plane
855 // vxmin: potential of lower x-plane
856 // Similar for ixmax, iymin, iymax, izmin, izmax
857 int ixmin, ixmax, iymin, iymax, izmin, izmax;
858 double cxmin, cxmax, cymin, cymax, czmin, czmax;
859 double vxmin, vxmax, vymin, vymax, vzmin, vzmax;
860 fstatus = neBEMGetBoundingPlanes(
861 &ixmin, &cxmin, &vxmin, &ixmax, &cxmax, &vxmax, &iymin, &cymin, &vymin,
862 &iymax, &cymax, &vymax, &izmin, &czmin, &vzmin, &izmax, &czmax, &vzmax);
863 if (fstatus != 0) {
864 neBEMMessage("neBEMReadGeometry - neBEMGetBoundingPlanes");
865 return -1;
866 }
867 BndPlaneInXMin[prim] = ixmin;
868 BndPlaneInXMax[prim] = ixmax;
869 BndPlaneInYMin[prim] = iymin;
870 BndPlaneInYMax[prim] = iymax;
871 BndPlaneInZMin[prim] = izmin;
872 BndPlaneInZMax[prim] = izmax;
873 if (ixmin) {
874 XBndPlaneInXMin[prim] = cxmin;
875 VBndPlaneInXMin[prim] = vxmin;
876 } else {
877 XBndPlaneInXMin[prim] = 0.0;
878 VBndPlaneInXMin[prim] = 0.0;
879 }
880 if (ixmax > 0) {
881 XBndPlaneInXMax[prim] = cxmax;
882 VBndPlaneInXMax[prim] = vxmax;
883 } else {
884 XBndPlaneInXMax[prim] = 0.0;
885 VBndPlaneInXMax[prim] = 0.0;
886 }
887 if (iymin > 0) {
888 YBndPlaneInYMin[prim] = cymin;
889 VBndPlaneInYMin[prim] = vymin;
890 } else {
891 YBndPlaneInYMin[prim] = 0.0;
892 VBndPlaneInYMin[prim] = 0.0;
893 }
894 if (iymax > 0) {
895 YBndPlaneInYMax[prim] = cymax;
896 VBndPlaneInYMax[prim] = vymax;
897 } else {
898 YBndPlaneInYMax[prim] = 0.0;
899 VBndPlaneInYMax[prim] = 0.0;
900 }
901 if (izmin > 0) {
902 ZBndPlaneInZMin[prim] = czmin;
903 VBndPlaneInZMin[prim] = vzmin;
904 } else {
905 ZBndPlaneInZMin[prim] = 0.0;
906 VBndPlaneInZMin[prim] = 0.0;
907 }
908 if (izmax > 0) {
909 ZBndPlaneInZMax[prim] = czmax;
910 VBndPlaneInZMax[prim] = vzmax;
911 } else {
912 ZBndPlaneInZMax[prim] = 0.0;
913 VBndPlaneInZMax[prim] = 0.0;
914 }
915 } // loop over the primitives - major loop
916
917 VolMax = volmax; // Maximum nb of volumes in the problem
918 volRef = ivector(0, VolMax); // variables to store volume related infomration
919 volShape = ivector(0, VolMax);
925 for (int volref = 0; volref <= VolMax; ++volref) {
926 neBEMVolumeDescription(volref, &volShape[volref], &volMaterial[volref],
927 &volEpsilon[volref], &volPotential[volref],
928 &volCharge[volref], &volBoundaryType[volref]);
929 if (dbgFn) {
930 printf("volref: %d\n", volref);
931 printf("shape: %d, material: %d\n", volShape[volref],
932 volMaterial[volref]);
933 printf("eps: %lg, pot: %lg\n", volEpsilon[volref], volPotential[volref]);
934 printf("q: %lg, type: %d\n", volCharge[volref], volBoundaryType[volref]);
935 }
936 }
937
938 // Ignore unnecessary primitives from the final count
939 // Ideally, all the removal conditions for a primitive should be checked in
940 // one loop and the list should be updated in one single go.
941 {
942 for (int prim = 1; prim <= NbPrimitives; ++prim) {
943 OrgnlToEffPrim[prim][0] = prim;
944 OrgnlToEffPrim[prim][1] = prim;
945 OrgnlToEffPrim[prim][2] = prim;
946 }
947
948 { // Skip primitive
949 // Remove skipped primitives having InterfaceType == 0.
950 // Also remove primitives having too small dimensions.
951 int NbSkipped = 0, effprim;
952 double DVertex[4], minDVertex = 0.0; // maximum number of vertices is 4
953 for (int prim = 1; prim <= NbPrimitives; ++prim) {
954 effprim = prim - NbSkipped;
955
956 // Check dimensions of the primitive
957 for (int vert = 0; vert < NbVertices[prim] - 1; ++vert) {
958 DVertex[vert] =
959 sqrt(((XVertex[prim][vert + 1] - XVertex[prim][vert]) *
960 (XVertex[prim][vert + 1] - XVertex[prim][vert])) +
961 ((YVertex[prim][vert + 1] - YVertex[prim][vert]) *
962 (YVertex[prim][vert + 1] - YVertex[prim][vert])) +
963 ((ZVertex[prim][vert + 1] - ZVertex[prim][vert]) *
964 (ZVertex[prim][vert + 1] - ZVertex[prim][vert])));
965 if (vert == 0)
966 minDVertex = DVertex[vert];
967 else {
968 if (DVertex[vert] < minDVertex) minDVertex = DVertex[vert];
969 }
970 }
971
972 if ((InterfaceType[prim]) && (minDVertex > MINDIST)) {
973 OrgnlToEffPrim[prim][1] = effprim;
974 OrgnlToEffPrim[prim][2] = effprim;
975 PrimType[effprim] = PrimType[prim];
976 NbVertices[effprim] = NbVertices[prim];
977 for (int vert = 0; vert < NbVertices[effprim]; ++vert) {
978 XVertex[effprim][vert] = XVertex[prim][vert];
979 YVertex[effprim][vert] = YVertex[prim][vert];
980 ZVertex[effprim][vert] = ZVertex[prim][vert];
981 }
982 if (PrimType[effprim] == 2) // wire
983 {
984 XNorm[effprim] = 0.0; // modulus not 1 - an absurd trio!
985 YNorm[effprim] = 0.0;
986 ZNorm[effprim] = 0.0;
987 Radius[effprim] = Radius[prim];
988 }
989 if ((PrimType[effprim] == 3) || (PrimType[effprim] == 4)) {
990 XNorm[effprim] = XNorm[prim];
991 YNorm[effprim] = YNorm[prim];
992 ZNorm[effprim] = ZNorm[prim];
993 Radius[effprim] = 0.0; // absurd radius!
994 }
995 VolRef1[effprim] = VolRef1[prim];
996 VolRef2[effprim] = VolRef2[prim];
997
998 InterfaceType[effprim] = InterfaceType[prim];
999 Epsilon1[effprim] = Epsilon1[prim];
1000 Epsilon2[effprim] = Epsilon2[prim];
1001 Lambda[effprim] = Lambda[prim];
1002 ApplPot[effprim] = ApplPot[prim];
1003 ApplCh[effprim] = ApplCh[prim];
1004 PeriodicTypeX[effprim] = PeriodicTypeX[prim];
1005 PeriodicTypeY[effprim] = PeriodicTypeY[prim];
1006 PeriodicTypeZ[effprim] = PeriodicTypeZ[prim];
1007 PeriodicInX[effprim] = PeriodicInX[prim];
1008 PeriodicInY[effprim] = PeriodicInY[prim];
1009 PeriodicInZ[effprim] = PeriodicInZ[prim];
1010 XPeriod[effprim] = XPeriod[prim];
1011 YPeriod[effprim] = YPeriod[prim];
1012 ZPeriod[effprim] = ZPeriod[prim];
1013 MirrorTypeX[effprim] = MirrorTypeX[prim];
1014 MirrorTypeY[effprim] = MirrorTypeY[prim];
1015 MirrorTypeZ[effprim] = MirrorTypeZ[prim];
1019 BndPlaneInXMin[effprim] = BndPlaneInXMin[prim];
1020 BndPlaneInXMax[effprim] = BndPlaneInXMax[prim];
1021 BndPlaneInYMin[effprim] = BndPlaneInYMin[prim];
1022 BndPlaneInYMax[effprim] = BndPlaneInYMax[prim];
1023 BndPlaneInZMin[effprim] = BndPlaneInZMin[prim];
1024 BndPlaneInZMax[effprim] = BndPlaneInZMax[prim];
1025 XBndPlaneInXMin[effprim] = XBndPlaneInXMin[prim];
1026 XBndPlaneInXMax[effprim] = XBndPlaneInXMax[prim];
1027 YBndPlaneInYMin[effprim] = YBndPlaneInYMin[prim];
1028 YBndPlaneInYMax[effprim] = YBndPlaneInYMax[prim];
1029 ZBndPlaneInZMin[effprim] = ZBndPlaneInZMin[prim];
1030 ZBndPlaneInZMax[effprim] = ZBndPlaneInZMax[prim];
1031 VBndPlaneInXMin[effprim] = VBndPlaneInXMin[prim];
1032 VBndPlaneInXMax[effprim] = VBndPlaneInXMax[prim];
1033 VBndPlaneInYMin[effprim] = VBndPlaneInYMin[prim];
1034 VBndPlaneInYMax[effprim] = VBndPlaneInYMax[prim];
1035 VBndPlaneInZMin[effprim] = VBndPlaneInZMin[prim];
1036 VBndPlaneInZMax[effprim] = VBndPlaneInZMax[prim];
1037 } // InterfaceType
1038 else {
1039 OrgnlToEffPrim[prim][1] = 0; // removed from the list
1040 OrgnlToEffPrim[prim][2] = 0;
1041 ++NbSkipped;
1042 if (DebugLevel == 101) {
1043 printf("Skipped primitive %d, InterfaceType: %d, minDVertex: %lg\n",
1044 prim, InterfaceType[prim], minDVertex);
1045 }
1046 }
1047 } // loop over primitives to remove the skipped primitives
1048 NbPrimitives -= NbSkipped;
1049 printf("Number of primitives skipped: %d, Effective NbPrimitives: %d\n",
1050 NbSkipped, NbPrimitives);
1051 } // Skip primitives
1052
1053 if (OptRmPrim) {
1054 int NbRmPrims;
1055 FILE *rmprimFile = fopen("neBEMInp/neBEMRmPrim.inp", "r");
1056 if (rmprimFile == NULL) {
1057 printf("neBEMRmPrim.inp absent ... assuming defaults ...\n");
1058 NbRmPrims = 0;
1059 } else {
1060 fscanf(rmprimFile, "NbRmPrims: %d\n", &NbRmPrims);
1061 if (NbRmPrims) {
1062 int tint;
1063#ifdef __cplusplus
1064 std::vector<double> rmXNorm(NbRmPrims + 1, 0.);
1065 std::vector<double> rmYNorm(NbRmPrims + 1, 0.);
1066 std::vector<double> rmZNorm(NbRmPrims + 1, 0.);
1067 std::vector<double> rmXVert(NbRmPrims + 1, 0.);
1068 std::vector<double> rmYVert(NbRmPrims + 1, 0.);
1069 std::vector<double> rmZVert(NbRmPrims + 1, 0.);
1070#else
1071 double rmXNorm[NbRmPrims + 1], rmYNorm[NbRmPrims + 1];
1072 double rmZNorm[NbRmPrims + 1];
1073 double rmXVert[NbRmPrims + 1], rmYVert[NbRmPrims + 1];
1074 double rmZVert[NbRmPrims + 1];
1075#endif
1076 for (int rmprim = 1; rmprim <= NbRmPrims; ++rmprim) {
1077 fscanf(rmprimFile, "Prim: %d\n", &tint);
1078 fscanf(rmprimFile, "rmXNorm: %le\n", &rmXNorm[rmprim]);
1079 fscanf(rmprimFile, "rmYNorm: %le\n", &rmYNorm[rmprim]);
1080 fscanf(rmprimFile, "rmZNorm: %le\n", &rmZNorm[rmprim]);
1081 fscanf(rmprimFile, "rmXVert: %le\n", &rmXVert[rmprim]);
1082 fscanf(rmprimFile, "rmYVert: %le\n", &rmYVert[rmprim]);
1083 fscanf(rmprimFile, "rmZVert: %le\n", &rmZVert[rmprim]);
1084 printf(
1085 "rmprim: %d, rmXNorm: %lg, rmYNorm: %lg, rmZNorm: %lg, "
1086 "rmXVert: %lg, rmYVert: %lg, rmZVert: %lg\n",
1087 rmprim, rmXNorm[rmprim], rmYNorm[rmprim], rmZNorm[rmprim],
1088 rmXVert[rmprim], rmYVert[rmprim], rmZVert[rmprim]);
1089 }
1090#ifdef __cplusplus
1091 std::vector<int> remove(NbPrimitives + 1, 0);
1092#else
1093 int remove[NbPrimitives + 1];
1094#endif
1095 // Check updated prim list
1096 for (int prim = 1; prim <= NbPrimitives; ++prim) {
1097 remove[prim] = 0;
1098 if (dbgFn) {
1099 printf("\n\nprim: %d, XVertex: %lg, YVertex: %lg, ZVertex: %lg\n",
1100 prim, XVertex[prim][0], YVertex[prim][0],
1101 ZVertex[prim][0]);
1102 printf("XNorm: %lg, YNorm: %lg, ZNorm: %lg\n", XNorm[prim],
1103 YNorm[prim], ZNorm[prim]);
1104 }
1105
1106 for (int rmprim = 1; rmprim <= NbRmPrims; ++rmprim) {
1107 if (dbgFn) {
1108 printf(
1109 "rmprim: %d, rmXVertex: %lg, rmYVertex: %lg, rmZVertex: "
1110 "%lg\n",
1111 rmprim, rmXVert[rmprim], rmYVert[rmprim], rmZVert[rmprim]);
1112 printf("rmXNorm: %lg, rmYNorm: %lg, rmZNorm: %lg\n",
1113 rmXNorm[rmprim], rmYNorm[rmprim], rmZNorm[rmprim]);
1114 }
1115
1116 // check the normal
1117 if ((fabs(fabs(XNorm[prim]) - fabs(rmXNorm[rmprim])) <=
1118 MINDIST) &&
1119 (fabs(fabs(YNorm[prim]) - fabs(rmYNorm[rmprim])) <=
1120 MINDIST) &&
1121 (fabs(fabs(ZNorm[prim]) - fabs(rmZNorm[rmprim])) <=
1122 MINDIST)) { // prim and rmprim are parallel
1123 // coplanarity check to be implemented later.
1124 // For the time-being, we will assume that the planes to be
1125 // removed have their normals parallel to a given axis. So, we
1126 // only check that and remove the primitive if the distace along
1127 // that axis match. Possible pitfall => the primitives may be
1128 // coplanar but non-overlapping!
1129 if (fabs(fabs(XNorm[prim]) - 1.0) <= 1.0e-12) {
1130 // primitive || to YZ
1131 if (fabs(XVertex[prim][0] - rmXVert[rmprim]) <= MINDIST) {
1132 remove[prim] = 1;
1133 }
1134 }
1135 if (fabs(fabs(YNorm[prim]) - 1.0) <= 1.0e-12) {
1136 // primitive || to XZ
1137 if (fabs(YVertex[prim][0] - rmYVert[rmprim]) <= MINDIST) {
1138 remove[prim] = 1;
1139 }
1140 }
1141 if (fabs(fabs(ZNorm[prim]) - 1.0) <= 1.0e-12) {
1142 // primitive || to XY
1143 if (fabs(ZVertex[prim][0] - rmZVert[rmprim]) <= MINDIST) {
1144 remove[prim] = 1;
1145 }
1146 }
1147 } // case where prim and rmprim are parallel
1148 if (dbgFn) {
1149 printf("prim: %d, rmprim: %d, remove: %d\n", prim, rmprim,
1150 remove[prim]);
1151 }
1152 if (remove[prim] == 1)
1153 break; // once removed, no point checking others
1154 } // for rmprim - loop over all removal specification
1155
1156 } // for prim loop over all primitives
1157
1158 int NbRemoved = 0;
1159 char RmPrimFile[256];
1160 strcpy(RmPrimFile, NativePrimDir);
1161 strcat(RmPrimFile, "/RmPrims.info");
1162 FILE *fprrm = fopen(RmPrimFile, "w");
1163 if (fprrm == NULL) {
1164 printf(
1165 "error opening RmPrims.info file in write mode ... "
1166 "returning\n");
1167
1168 fclose(rmprimFile);
1169 return (-1);
1170 }
1171 // Note that some of the original primitives have already been removed
1172 // based on interface and dimension considerations
1173 int orgnlNb = 0;
1174 for (int prim = 1; prim <= NbPrimitives; ++prim) {
1175 // identify primitive number in the original list
1176 for (int orgnlprim = 1; orgnlprim <= OrgnlNbPrimitives;
1177 ++orgnlprim) {
1178 if (OrgnlToEffPrim[orgnlprim][1] ==
1179 prim) // number updated for intrfc
1180 {
1181 orgnlNb = orgnlprim;
1182 break;
1183 }
1184 } // loop for finding out its position in the original list
1185
1186 if (remove[prim] == 1) {
1187 ++NbRemoved;
1188 OrgnlToEffPrim[orgnlNb][2] = 0;
1189 fprintf(fprrm, "NbRemoved: %d, Removed primitive: %d\n",
1190 NbRemoved, prim);
1191 fprintf(fprrm, "PrimType: %d\n", PrimType[prim]);
1192 fprintf(fprrm, "NbVertices: %d\n", NbVertices[prim]);
1193 for (int vert = 0; vert < NbVertices[prim]; ++vert) {
1194 fprintf(fprrm, "Vertx %d: %lg, %lg, %lg\n", vert,
1195 XVertex[prim][vert], YVertex[prim][vert],
1196 ZVertex[prim][vert]);
1197 }
1198 fprintf(fprrm, "Normals: %lg, %lg, %lg\n", XNorm[prim],
1199 YNorm[prim], ZNorm[prim]);
1200 continue;
1201 } // if remove
1202 else { // keep this one in the updated list of primitives
1203 int effprim = prim - NbRemoved;
1204
1205 OrgnlToEffPrim[orgnlNb][2] = effprim;
1206 PrimType[effprim] = PrimType[prim];
1207 NbVertices[effprim] = NbVertices[prim];
1208 for (int vert = 0; vert < NbVertices[effprim]; ++vert) {
1209 XVertex[effprim][vert] = XVertex[prim][vert];
1210 YVertex[effprim][vert] = YVertex[prim][vert];
1211 ZVertex[effprim][vert] = ZVertex[prim][vert];
1212 }
1213 if (PrimType[effprim] == 2) {
1214 // wire
1215 XNorm[effprim] = 0.0; // modulus not 1 - an absurd trio!
1216 YNorm[effprim] = 0.0;
1217 ZNorm[effprim] = 0.0;
1218 Radius[effprim] = Radius[prim];
1219 }
1220 if ((PrimType[effprim] == 3) || (PrimType[effprim] == 4)) {
1221 XNorm[effprim] = XNorm[prim];
1222 YNorm[effprim] = YNorm[prim];
1223 ZNorm[effprim] = ZNorm[prim];
1224 Radius[effprim] = 0.0; // absurd radius!
1225 }
1226 VolRef1[effprim] = VolRef1[prim];
1227 VolRef2[effprim] = VolRef2[prim];
1228
1229 InterfaceType[effprim] = InterfaceType[prim];
1230 Epsilon1[effprim] = Epsilon1[prim];
1231 Epsilon2[effprim] = Epsilon2[prim];
1232 Lambda[effprim] = Lambda[prim];
1233 ApplPot[effprim] = ApplPot[prim];
1234 ApplCh[effprim] = ApplCh[prim];
1235 PeriodicTypeX[effprim] = PeriodicTypeX[prim];
1236 PeriodicTypeY[effprim] = PeriodicTypeY[prim];
1237 PeriodicTypeZ[effprim] = PeriodicTypeZ[prim];
1238 PeriodicInX[effprim] = PeriodicInX[prim];
1239 PeriodicInY[effprim] = PeriodicInY[prim];
1240 PeriodicInZ[effprim] = PeriodicInZ[prim];
1241 XPeriod[effprim] = XPeriod[prim];
1242 YPeriod[effprim] = YPeriod[prim];
1243 ZPeriod[effprim] = ZPeriod[prim];
1244 MirrorTypeX[effprim] = MirrorTypeX[prim];
1245 MirrorTypeY[effprim] = MirrorTypeY[prim];
1246 MirrorTypeZ[effprim] = MirrorTypeZ[prim];
1250 BndPlaneInXMin[effprim] = BndPlaneInXMin[prim];
1251 BndPlaneInXMax[effprim] = BndPlaneInXMax[prim];
1252 BndPlaneInYMin[effprim] = BndPlaneInYMin[prim];
1253 BndPlaneInYMax[effprim] = BndPlaneInYMax[prim];
1254 BndPlaneInZMin[effprim] = BndPlaneInZMin[prim];
1255 BndPlaneInZMax[effprim] = BndPlaneInZMax[prim];
1256 XBndPlaneInXMin[effprim] = XBndPlaneInXMin[prim];
1257 XBndPlaneInXMax[effprim] = XBndPlaneInXMax[prim];
1258 YBndPlaneInYMin[effprim] = YBndPlaneInYMin[prim];
1259 YBndPlaneInYMax[effprim] = YBndPlaneInYMax[prim];
1260 ZBndPlaneInZMin[effprim] = ZBndPlaneInZMin[prim];
1261 ZBndPlaneInZMax[effprim] = ZBndPlaneInZMax[prim];
1262 VBndPlaneInXMin[effprim] = VBndPlaneInXMin[prim];
1263 VBndPlaneInXMax[effprim] = VBndPlaneInXMax[prim];
1264 VBndPlaneInYMin[effprim] = VBndPlaneInYMin[prim];
1265 VBndPlaneInYMax[effprim] = VBndPlaneInYMax[prim];
1266 VBndPlaneInZMin[effprim] = VBndPlaneInZMin[prim];
1267 VBndPlaneInZMax[effprim] = VBndPlaneInZMax[prim];
1268 } // else remove == 0
1269 } // loop over primitives to remove the primitives tagged to be
1270 // removed
1271 fclose(fprrm);
1272
1273 NbPrimitives -= NbRemoved;
1274 printf(
1275 "Number of primitives removed: %d, Effective NbPrimitives: %d\n",
1276 NbRemoved, NbPrimitives);
1277 fflush(stdout);
1278 } // if NbRmPrims true, implying primitives need to be removed
1279 fclose(rmprimFile);
1280 } // if the rmprimFile is not NULL, prepare to remove primitives
1281 } // if OptRmPrim: remove primitives as desired by the user
1282
1283 // Information about primitives which are being ignored
1284 char IgnorePrimFile[256];
1285 strcpy(IgnorePrimFile, NativePrimDir);
1286 strcat(IgnorePrimFile, "/IgnorePrims.info");
1287 FILE *fignore = fopen(IgnorePrimFile, "w");
1288 if (fignore == NULL) {
1289 printf(
1290 "error opening IgnorePrims.info file in write mode ... returning\n");
1291 return (-1);
1292 }
1293
1294 for (int prim = 1; prim <= OrgnlNbPrimitives; ++prim) {
1295 fprintf(fignore, "%d %d %d\n", OrgnlToEffPrim[prim][0],
1296 OrgnlToEffPrim[prim][1], OrgnlToEffPrim[prim][2]);
1297 }
1298
1299 fclose(fignore);
1300 } // Ignore unnecessary primitives from the final count
1301
1302 // Reduced-Order Modelling information
1303 printf("ROM: switch to primitive representation after %d repetitions.\n",
1304 PrimAfter);
1305
1306 // Store model data in native neBEM format
1307 char NativeInFile[256];
1308
1309 strcpy(NativeInFile, NativeOutDir);
1310 strcat(NativeInFile, "/neBEMNative.inp");
1311 FILE *fNativeInFile = fopen(NativeInFile, "w");
1312 fprintf(fNativeInFile, "#====>Input directory\n");
1313 fprintf(fNativeInFile, "%s\n", NativePrimDir);
1314 fprintf(fNativeInFile, "#====>No. of primitives:\n");
1315 fprintf(fNativeInFile, "%d\n", NbPrimitives);
1316 fprintf(fNativeInFile, "#====>No. of volumes:\n");
1317 fprintf(fNativeInFile, "%d\n", VolMax);
1318 for (int prim = 1; prim <= NbPrimitives; ++prim) {
1319 char strPrimNb[11];
1320 snprintf(strPrimNb, 11, "%d", prim);
1321 char NativePrimFile[256];
1322 strcpy(NativePrimFile, "Primitive");
1323 strcat(NativePrimFile, strPrimNb);
1324 strcat(NativePrimFile, ".inp");
1325
1326 fprintf(fNativeInFile, "#Input filename for primitive:\n");
1327 fprintf(fNativeInFile, "%s\n", NativePrimFile);
1328
1329 strcpy(NativePrimFile, NativePrimDir);
1330 strcat(NativePrimFile, "/Primitive");
1331 strcat(NativePrimFile, strPrimNb);
1332 strcat(NativePrimFile, ".inp");
1333
1334 FILE *fNativePrim = fopen(NativePrimFile, "w");
1335
1336 fprintf(fNativePrim, "#Number of vertices:\n");
1337 fprintf(fNativePrim, "%d\n", NbVertices[prim]);
1338 for (int vertex = 0; vertex < NbVertices[prim]; ++vertex) {
1339 fprintf(fNativePrim, "#Vertex %d:\n", vertex);
1340 fprintf(fNativePrim, "%lg %lg %lg\n", XVertex[prim][vertex],
1341 YVertex[prim][vertex], ZVertex[prim][vertex]);
1342 } // for vertex
1343 fprintf(fNativePrim, "#Outward normal:\n");
1344 fprintf(fNativePrim, "%lg %lg %lg\n", XNorm[prim], YNorm[prim],
1345 ZNorm[prim]);
1346 fprintf(fNativePrim, "#Volume references:\n");
1347 fprintf(fNativePrim, "%d %d\n", VolRef1[prim], VolRef2[prim]);
1348 fprintf(fNativePrim, "#Maximum number of segments:\n");
1349 fprintf(fNativePrim, "%d %d\n", 0, 0); // use the trio target, min, max
1350 fprintf(fNativePrim, "#Information on X periodicity:\n");
1351 fprintf(fNativePrim, "%d %d %lg\n", PeriodicTypeX[prim], PeriodicInX[prim],
1352 XPeriod[prim]);
1353 fprintf(fNativePrim, "#Information on Y periodicity:\n");
1354 fprintf(fNativePrim, "%d %d %lg\n", PeriodicTypeY[prim], PeriodicInY[prim],
1355 YPeriod[prim]);
1356 fprintf(fNativePrim, "#Information on Z periodicity:\n");
1357 fprintf(fNativePrim, "%d %d %lg\n", PeriodicTypeZ[prim], PeriodicInZ[prim],
1358 ZPeriod[prim]);
1359
1360 fclose(fNativePrim);
1361 } // for prim
1362
1363 fprintf(fNativeInFile, "#====>No. of boundary conditions per element:\n");
1364 fprintf(fNativeInFile, "%d\n", 1); // CHECK!!!
1365 fprintf(fNativeInFile, "#====>Device output directory name:\n");
1366 fprintf(fNativeInFile, "NativeResults\n");
1367 fprintf(fNativeInFile, "#====>Map input file:\n");
1368 fprintf(fNativeInFile, "MapFile.inp\n");
1369 fclose(fNativeInFile);
1370
1371 for (int volume = 0; volume <= VolMax; ++volume) {
1372 // Note that materials from 1 to 10 are conductors and
1373 // from 11 to 20 are dielectrics
1374 int shape, material, boundarytype;
1375 double epsilon, potential, charge;
1376 neBEMVolumeDescription(volume, &shape, &material, &epsilon, &potential,
1377 &charge, &boundarytype);
1378
1379 char strVolNb[11];
1380 snprintf(strVolNb, 11, "%d", volume);
1381 char NativeVolFile[256];
1382 strcpy(NativeVolFile, NativePrimDir);
1383 strcat(NativeVolFile, "/Volume");
1384 strcat(NativeVolFile, strVolNb);
1385 strcat(NativeVolFile, ".inp");
1386
1387 FILE *fNativeVol = fopen(NativeVolFile, "w");
1388
1389 fprintf(fNativeVol, "#Shape of the volume:\n");
1390 fprintf(fNativeVol, "%d\n", shape);
1391 fprintf(fNativeVol, "#Material of the volume:\n");
1392 fprintf(fNativeVol, "%d\n", material);
1393 fprintf(fNativeVol, "#Relative permittivity:\n");
1394 fprintf(fNativeVol, "%lg\n", epsilon);
1395 fprintf(fNativeVol, "#Potential:\n");
1396 fprintf(fNativeVol, "%lg\n", potential);
1397 fprintf(fNativeVol, "#Charge:\n");
1398 fprintf(fNativeVol, "%lg\n", charge);
1399 fprintf(fNativeVol, "#Boundary type:\n");
1400 fprintf(fNativeVol, "%d\n", boundarytype);
1401
1402 fclose(fNativeVol);
1403 }
1404
1405 // create a dummy map file
1406 {
1407 char NativeMapFile[256];
1408
1409 strcpy(NativeMapFile, NativePrimDir);
1410 strcat(NativeMapFile, "/MapFile.inp");
1411
1412 FILE *fNativeMap = fopen(NativeMapFile, "w");
1413
1414 fprintf(fNativeMap, "#Number of maps\n");
1415 fprintf(fNativeMap, "%d\n", 0);
1416 fprintf(fNativeMap, "#Number of lines\n");
1417 fprintf(fNativeMap, "%d\n", 0);
1418 fprintf(fNativeMap, "#Number of points\n");
1419 fprintf(fNativeMap, "%d\n", 0);
1420
1421 fclose(fNativeMap);
1422 }
1423
1424 // Store primitive related data in a file for a new model, if opted for
1426 if (OptFormattedFile) {
1427 fstatus = WritePrimitives();
1428 if (fstatus) {
1429 neBEMMessage("neBEMReadGeometry - problem writing Primtives.\n");
1430 return -1;
1431 }
1432 } // formatted file
1433
1434 if (OptUnformattedFile) {
1436 "neBEMReadGeometry - unformatted write not inplemented yet.\n");
1437 return -1;
1438 } // unformatted file
1439 } // store primitives
1440
1441 printf("neBEMReadGeometry: Geometry read!\n");
1442
1443 neBEMState = 3; // info about primitives read in after initialization and Nbs
1444
1445 stopClock = clock();
1447 printf("to read geometry\n");
1448
1449 return (0); // Success!
1450} // neBEMReadGeometry ends
DoubleAc fabs(const DoubleAc &f)
Definition DoubleAc.h:615
DoubleAc sqrt(const DoubleAc &f)
Definition DoubleAc.cpp:314
int WritePrimitives(void)
int ReadPrimitives(void)
INTFACEGLOBAL int neBEMGetBoundingPlanes(int *ixmin, double *cxmin, double *vxmin, int *ixmax, double *cxmax, double *vxmax, int *iymin, double *cymin, double *vymin, int *iymax, double *cymax, double *vymax, int *izmin, double *czmin, double *vzmin, int *izmax, double *czmax, double *vzmax)
INTFACEGLOBAL int neBEMVolumeDescription(int ivol, int *shape, int *material, double *epsilon, double *potential, double *charge, int *boundarytype)
INTFACEGLOBAL int neBEMGetNbPrimitives(void)
INTFACEGLOBAL int OptPrintVolumeDetails
INTFACEGLOBAL int neBEMGetPrimitive(int prim, int *nvertex, double xvert[], double yvert[], double zvert[], double *xnorm, double *ynorm, double *znorm, int *volref1, int *volref2)
INTFACEGLOBAL int neBEMGetMirror(int prim, int *ix, int *jx, double *sx, int *iy, int *jy, double *sy, int *iz, int *jz, double *sz)
INTFACEGLOBAL int OptPrintPrimaryDetails
INTFACEGLOBAL int neBEMGetPeriodicities(int prim, int *ix, int *jx, double *sx, int *iy, int *jy, double *sy, int *iz, int *jz, double *sz)
neBEMGLOBAL int * PeriodicInY
Definition neBEM.h:86
neBEMGLOBAL int * volMaterial
Definition neBEM.h:70
neBEMGLOBAL int * NbElmntsOnPrim
Definition neBEM.h:101
neBEMGLOBAL int OptRmPrim
Definition neBEM.h:53
neBEMGLOBAL int * MirrorTypeZ
Definition neBEM.h:88
neBEMGLOBAL double * MirrorDistYFromOrigin
Definition neBEM.h:89
neBEMGLOBAL int OptStorePrimitives
Definition neBEM.h:51
neBEMGLOBAL int MaxNbVertices
Definition neBEM.h:66
neBEMGLOBAL int * BndPlaneInYMax
Definition neBEM.h:92
neBEMGLOBAL double * XBndPlaneInXMax
Definition neBEM.h:94
neBEMGLOBAL double * YBndPlaneInYMin
Definition neBEM.h:93
neBEMGLOBAL int ** OrgnlToEffPrim
Definition neBEM.h:76
neBEMGLOBAL double * ZPeriod
Definition neBEM.h:87
neBEMGLOBAL double * VBndPlaneInZMin
Definition neBEM.h:95
neBEMGLOBAL int * BndPlaneInXMax
Definition neBEM.h:92
neBEMGLOBAL double * YBndPlaneInYMax
Definition neBEM.h:94
neBEMGLOBAL double * PrimOriginZ
Definition neBEM.h:80
neBEMGLOBAL int * PeriodicTypeX
Definition neBEM.h:85
neBEMGLOBAL double * VBndPlaneInYMax
Definition neBEM.h:96
neBEMGLOBAL double * ZBndPlaneInZMax
Definition neBEM.h:94
neBEMGLOBAL int * PeriodicTypeY
Definition neBEM.h:85
neBEMGLOBAL double * Epsilon1
Definition neBEM.h:82
neBEMGLOBAL double * PrimOriginY
Definition neBEM.h:80
neBEMGLOBAL double * MirrorDistZFromOrigin
Definition neBEM.h:90
neBEMGLOBAL DirnCosn3D * PrimDC
Definition neBEM.h:81
neBEMGLOBAL int * BndPlaneInZMin
Definition neBEM.h:91
neBEMGLOBAL double * VBndPlaneInXMin
Definition neBEM.h:95
neBEMGLOBAL int NbFloatingConductors
Definition neBEM.h:131
neBEMGLOBAL double * XPeriod
Definition neBEM.h:87
neBEMGLOBAL double * volEpsilon
Definition neBEM.h:71
neBEMGLOBAL int * volRef
Definition neBEM.h:70
neBEMGLOBAL double * volPotential
Definition neBEM.h:71
neBEMGLOBAL double * VBndPlaneInZMax
Definition neBEM.h:96
neBEMGLOBAL double * AvAsgndChDen
Definition neBEM.h:97
neBEMGLOBAL double * XBndPlaneInXMin
Definition neBEM.h:93
neBEMGLOBAL int * BndPlaneInXMin
Definition neBEM.h:91
neBEMGLOBAL int * MirrorTypeY
Definition neBEM.h:88
neBEMGLOBAL double * AvChDen
Definition neBEM.h:97
neBEMGLOBAL int * MirrorTypeX
Definition neBEM.h:88
neBEMGLOBAL int * BndPlaneInZMax
Definition neBEM.h:92
neBEMGLOBAL int * BndPlaneInYMin
Definition neBEM.h:91
neBEMGLOBAL double * PrimLX
Definition neBEM.h:79
neBEMGLOBAL double * PrimOriginX
Definition neBEM.h:80
neBEMGLOBAL int * PeriodicInZ
Definition neBEM.h:86
neBEMGLOBAL int * PeriodicInX
Definition neBEM.h:86
neBEMGLOBAL double * ZBndPlaneInZMin
Definition neBEM.h:93
neBEMGLOBAL double * VBndPlaneInYMin
Definition neBEM.h:95
neBEMGLOBAL double * volCharge
Definition neBEM.h:71
neBEMGLOBAL int OrgnlNbPrimitives
Definition neBEM.h:65
neBEMGLOBAL int * volBoundaryType
Definition neBEM.h:70
neBEMGLOBAL int * PeriodicTypeZ
Definition neBEM.h:85
neBEMGLOBAL int VolMax
Definition neBEM.h:84
neBEMGLOBAL double * YPeriod
Definition neBEM.h:87
neBEMGLOBAL double * PrimLZ
Definition neBEM.h:79
neBEMGLOBAL int * volShape
Definition neBEM.h:70
neBEMGLOBAL double * MirrorDistXFromOrigin
Definition neBEM.h:89
neBEMGLOBAL double * VBndPlaneInXMax
Definition neBEM.h:96
neBEMGLOBAL double * Epsilon2
Definition neBEM.h:82
double ** dmatrix(long nrl, long nrh, long ncl, long nch)
Definition nrutil.c:98
int ** imatrix(long nrl, long nrh, long ncl, long nch)
Definition nrutil.c:122

◆ neBEMSetDefaults()

INTFACEGLOBAL int neBEMSetDefaults ( void )

◆ neBEMSolve()

INTFACEGLOBAL int neBEMSolve ( void )

Definition at line 1811 of file neBEMInterface.c.

1811 {
1812 int dbgFn = 0;
1813
1814 clock_t startSolveClock = clock();
1815
1816 if (TimeStep < 1) {
1817 neBEMMessage("neBEMSolve - TimeStep cannot be less than one!;\n");
1818 neBEMMessage(" Please put TimeStep = 1 for static problems.\n");
1819 }
1820
1821 if ((neBEMState == 5) || (neBEMState == 8)) {
1822 if (neBEMState == 8) // neBEMState 8 must have inverted flag on
1823 { // so it must be a case looking for solution with a NewBC
1824 if (NewBC == 0) {
1825 neBEMMessage("neBEMSolve - NewBC zero for neBEMState = 8!");
1826 neBEMMessage(" - Nothing to be done ... returning.");
1827 return -1;
1828 }
1829 }
1830
1831 if (NewModel) { // effectively, NewMesh = NewBC = NewPP = 1;
1832 int fstatus = ComputeSolution();
1833 if (fstatus != 0) {
1834 neBEMMessage("neBEMSolve - NewModel");
1835 return -1;
1836 }
1837 } else { // NewModel == 0
1838 if (NewMesh) {
1839 // effectively, NewBC = NewPP = 1;
1840 int fstatus = ComputeSolution();
1841 if (fstatus != 0) {
1842 neBEMMessage("neBEMSolve - NewMesh");
1843 return -1;
1844 }
1845 } else { // NewModel == NewMesh == 0
1846 if (NewBC) { // effectively, NewPP = 1;
1847 int fstatus = ComputeSolution();
1848 if (fstatus != 0) {
1849 neBEMMessage("neBEMSolve - Failure computing new solution");
1850 return -1;
1851 }
1852 } else { // NewBC == 0
1853 if (NewPP) {
1854 int fstatus = ReadSolution();
1855 if (fstatus != 0) {
1856 neBEMMessage("neBEMSolve - Failure reading solution");
1857 return (-1);
1858 }
1859 } else { // NewPP == 0
1860 printf("neBEMSolve: Nothing to do ... returning ...\n");
1861 return (-1);
1862 } // NewPP == 0
1863 } // NewBC == 0
1864 } // NewModel == NewDiscretization == 0
1865 } // NewModel == 0
1866
1867 neBEMState = 9;
1868 } else {
1869 printf("neBEMSolve: neBEMSolve can be called only in state 5 / 8 ...\n");
1870 printf("returning ...\n");
1871 return (-1);
1872 }
1873
1874 if (FailureCntr) {
1875 printf(
1876 "neBEMSolve: Approximations were made while computing the influence "
1877 "coefficients.\n");
1878 printf(" Please check the \"%s/Isles.log\" file.\n", PPOutDir);
1879 }
1880
1881 clock_t stopSolveClock = clock();
1882 neBEMTimeElapsed(startSolveClock, stopSolveClock);
1883 printf("to complete solve\n");
1884
1885 // Prepare voxelized data that will be exported to Garfield++
1886 if (OptVoxel) {
1887 clock_t startVoxelClock = clock();
1888
1889 int fstatus = VoxelFPR();
1890 if (fstatus != 0) {
1891 neBEMMessage("neBEMSolve - Failure computing VoxelFPR");
1892 return -1;
1893 }
1894
1895 clock_t stopVoxelClock = clock();
1896 neBEMTimeElapsed(startVoxelClock, stopVoxelClock);
1897 printf("to compute VoxelFPR\n");
1898 }
1899
1900 // Prepare 3dMap data that will be exported to Garfield++
1901 if (OptMap) {
1902 clock_t startMapClock = clock();
1903
1904 int fstatus = MapFPR();
1905 if (fstatus != 0) {
1906 neBEMMessage("neBEMSolve - Failure computing MapFPR");
1907 return -1;
1908 }
1909
1910 clock_t stopMapClock = clock();
1911 neBEMTimeElapsed(startMapClock, stopMapClock);
1912 printf("to compute MapFPR\n");
1913 }
1914
1915 // allocate memory for potential and field components within FAST volume mesh
1916 // and compute / read FastVol data
1917 // Similar allocation, computation and reading may be necessary for the KnCh
1918 // effects.
1919 // The other approach could be to create fast volumes that always have both
1920 // the influences (elements + known charges) added together. This approach
1921 // seems more managable now and is being followed.
1922 // Thus, if we want to inspect the effects of elements and known charges
1923 // separately, we will have to generate one fast volume with OptKnCh = 0,
1924 // and another with OptKnCh = 1. Subtraction of these two fast volumes will
1925 // provide us with the effect of KnCh.
1926 if (OptFastVol) {
1927 int MaxXCells = BlkNbXCells[1];
1928 int MaxYCells = BlkNbYCells[1];
1929 int MaxZCells = BlkNbZCells[1];
1930 clock_t startFastClock = clock();
1931
1932 // find maximum number of Xcells etc in all the blocks
1933 // simplifies memory allocation using nrutils but hogs memory!
1934 for (int block = 1; block <= FastVol.NbBlocks; ++block) {
1935 if (block == 1) {
1936 MaxXCells = BlkNbXCells[1];
1937 MaxYCells = BlkNbYCells[1];
1938 MaxZCells = BlkNbZCells[1];
1939 } else {
1940 if (MaxXCells < BlkNbXCells[block]) MaxXCells = BlkNbXCells[block];
1941 if (MaxYCells < BlkNbYCells[block]) MaxYCells = BlkNbYCells[block];
1942 if (MaxZCells < BlkNbZCells[block]) MaxZCells = BlkNbZCells[block];
1943 }
1944 } // loop block for finding maxm cells among all the blocks
1945
1946 if (dbgFn) {
1947 printf("OptFastVol: %d\n", OptFastVol);
1948 printf("NbPtSkip: %d\n", NbPtSkip);
1949 printf("OptStaggerFastVol: %d\n", OptStaggerFastVol);
1950 printf("NbStgPtSkip: %d\n", NbStgPtSkip);
1951 printf("OptReadFastPF: %d\n", OptReadFastPF);
1952 printf("LX: %le\n", FastVol.LX);
1953 printf("LY: %le\n", FastVol.LY);
1954 printf("LZ: %le\n", FastVol.LZ);
1955 printf("CornerX: %le\n", FastVol.CrnrX);
1956 printf("CornerY: %le\n", FastVol.CrnrY);
1957 printf("CornerZ: %le\n", FastVol.CrnrZ);
1958 printf("YStagger: %le\n", FastVol.YStagger);
1959 printf("NbOfBlocks: %d\n", FastVol.NbBlocks);
1960 for (int block = 1; block <= FastVol.NbBlocks; ++block) {
1961 printf("NbOfXCells[%d]: %d\n", block, BlkNbXCells[block]);
1962 printf("NbOfYCells[%d]: %d\n", block, BlkNbYCells[block]);
1963 printf("NbOfZCells[%d]: %d\n", block, BlkNbZCells[block]);
1964 printf("LZ[%d]: %le\n", block, BlkLZ[block]);
1965 printf("CornerZ[%d]: %le\n", block, BlkCrnrZ[block]);
1966 }
1967 printf("NbOfOmitVols: %d\n", FastVol.NbOmitVols);
1968 if (FastVol.NbOmitVols) {
1969 for (int omit = 1; omit <= FastVol.NbOmitVols; ++omit) {
1970 printf("OmitVolLX[%d]: %le\n", omit, OmitVolLX[omit]);
1971 printf("OmitVolLY[%d]: %le\n", omit, OmitVolLY[omit]);
1972 printf("OmitVolLZ[%d]: %le\n", omit, OmitVolLZ[omit]);
1973 printf("OmitCrnrX[%d]: %le\n", omit, OmitVolCrnrX[omit]);
1974 printf("OmitCrnrY[%d]: %le\n", omit, OmitVolCrnrY[omit]);
1975 printf("OmitCrnrZ[%d]: %le\n", omit, OmitVolCrnrZ[omit]);
1976 }
1977 }
1978 printf("MaxXCells, MaxYCells, MaxZCells: %d, %d, %d\n", MaxXCells,
1979 MaxYCells, MaxZCells);
1980 } // dbgFn
1981
1982 // Following memory allocations are necessary even for creating
1983 // the fast volumes.
1984 // In fact, since these tensors are already in place, the fast volumes
1985 // can be used to evaluate potential and fields immediately after they are
1986 // created.
1987 /* Memory wastage!!! Improve as soon as possible. */
1988 FastPot = d4tensor(1, FastVol.NbBlocks, 1, MaxXCells + 1, 1, MaxYCells + 1,
1989 1, MaxZCells + 1);
1990 FastFX = d4tensor(1, FastVol.NbBlocks, 1, MaxXCells + 1, 1, MaxYCells + 1,
1991 1, MaxZCells + 1);
1992 FastFY = d4tensor(1, FastVol.NbBlocks, 1, MaxXCells + 1, 1, MaxYCells + 1,
1993 1, MaxZCells + 1);
1994 FastFZ = d4tensor(1, FastVol.NbBlocks, 1, MaxXCells + 1, 1, MaxYCells + 1,
1995 1, MaxZCells + 1);
1996
1997 if (OptStaggerFastVol) {
1998 /* Memory wastage!!! Improve as soon as possible. */
1999 StgFastPot = d4tensor(1, FastVol.NbBlocks, 1, MaxXCells + 1, 1,
2000 MaxYCells + 1, 1, MaxZCells + 1);
2001 StgFastFX = d4tensor(1, FastVol.NbBlocks, 1, MaxXCells + 1, 1,
2002 MaxYCells + 1, 1, MaxZCells + 1);
2003 StgFastFY = d4tensor(1, FastVol.NbBlocks, 1, MaxXCells + 1, 1,
2004 MaxYCells + 1, 1, MaxZCells + 1);
2005 StgFastFZ = d4tensor(1, FastVol.NbBlocks, 1, MaxXCells + 1, 1,
2006 MaxYCells + 1, 1, MaxZCells + 1);
2007 } // if OptStaggerFastVol
2008
2009 if (OptCreateFastPF) {
2010 int fstatus = CreateFastVolPF();
2011 if (fstatus != 0) {
2012 neBEMMessage("neBEMSolve - Failure computing FastVolPF");
2013 return -1;
2014 }
2015
2016 clock_t stopFastClock = clock();
2017 neBEMTimeElapsed(startFastClock, stopFastClock);
2018 printf("to compute FastVolPF\n");
2019 } // if OptCreateFastPF
2020
2021 if (OptReadFastPF) { // reading from file
2022 int nbXCells, nbYCells, nbZCells;
2023 int tmpblk;
2024 double xpt, ypt, zpt;
2025
2026 char FastVolPFFile[256];
2027 strcpy(FastVolPFFile, BCOutDir);
2028 strcat(FastVolPFFile, "/FastVolPF.out");
2029 FILE *fFastVolPF = fopen(FastVolPFFile, "r");
2030 if (fFastVolPF == NULL) {
2031 neBEMMessage("in neBEMSolve - FastVolPFFile");
2032 return -1;
2033 }
2034
2035 fscanf(fFastVolPF, "#block\tX\tY\tZ\tPot\tFX\tFY\tFZ\n");
2036
2037 for (int block = 1; block <= FastVol.NbBlocks; ++block) {
2038 nbXCells = BlkNbXCells[block];
2039 nbYCells = BlkNbYCells[block];
2040 nbZCells = BlkNbZCells[block];
2041
2042 for (int i = 1; i <= nbXCells + 1; ++i) {
2043 for (int j = 1; j <= nbYCells + 1; ++j) {
2044 for (int k = 1; k <= nbZCells + 1; ++k) {
2045 fscanf(fFastVolPF, "%d\t%le\t%le\t%le\t%le\t%le\t%le\t%le\n",
2046 &tmpblk, &xpt, &ypt, &zpt, &FastPot[block][i][j][k],
2047 &FastFX[block][i][j][k], &FastFY[block][i][j][k],
2048 &FastFZ[block][i][j][k]);
2049 } // loop k
2050 } // loop j
2051 } // loop i
2052 } // loop block
2053 fclose(fFastVolPF);
2054
2055 if (OptStaggerFastVol) {
2056 char StgFastVolPFFile[256];
2057 strcpy(StgFastVolPFFile, BCOutDir);
2058 strcat(StgFastVolPFFile, "/StgFastVolPF.out");
2059 FILE *fStgFastVolPF = fopen(StgFastVolPFFile, "r");
2060 if (fStgFastVolPF == NULL) {
2061 neBEMMessage("in neBEMSolve - StgFastVolPFFile");
2062 return -1;
2063 }
2064
2065 fscanf(fStgFastVolPF, "#block\tX\tY\tZ\tPot\tFX\tFY\tFZ\n");
2066
2067 for (int block = 1; block <= FastVol.NbBlocks; ++block) {
2068 nbXCells = BlkNbXCells[block];
2069 nbYCells = BlkNbYCells[block];
2070 nbZCells = BlkNbZCells[block];
2071
2072 for (int i = 1; i <= nbXCells + 1; ++i) {
2073 for (int j = 1; j <= nbYCells + 1; ++j) {
2074 for (int k = 1; k <= nbZCells + 1; ++k) {
2075 fscanf(fStgFastVolPF, "%d\t%le\t%le\t%le\t%le\t%le\t%le\t%le\n",
2076 &tmpblk, &xpt, &ypt, &zpt, &StgFastPot[block][i][j][k],
2077 &StgFastFX[block][i][j][k], &StgFastFY[block][i][j][k],
2078 &StgFastFZ[block][i][j][k]);
2079 } // loop k
2080 } // loop j
2081 } // loop i
2082 } // loop block
2083 fclose(fStgFastVolPF);
2084 } // if OptStaggerFastVol
2085
2086 clock_t stopFastClock = clock();
2087 neBEMTimeElapsed(startFastClock, stopFastClock);
2088 printf("to read FastVolPF\n");
2089 } // if OptReadFastPF
2090 } // if OptFastVol
2091
2092 return (0);
2093} // neBEMSolve ends
int VoxelFPR(void)
int MapFPR(void)
int CreateFastVolPF(void)
int ComputeSolution(void)
Definition neBEM.c:35
int ReadSolution(void)
Definition neBEM.c:3963
neBEMGLOBAL double **** FastFY
Definition neBEM.h:461
neBEMGLOBAL double **** FastFZ
Definition neBEM.h:461
neBEMGLOBAL double **** StgFastFY
Definition neBEM.h:463
neBEMGLOBAL double **** StgFastFZ
Definition neBEM.h:463
neBEMGLOBAL double **** FastFX
Definition neBEM.h:461
neBEMGLOBAL int TimeStep
Definition neBEM.h:201
neBEMGLOBAL double **** FastPot
Definition neBEM.h:460
neBEMGLOBAL double **** StgFastFX
Definition neBEM.h:463
neBEMGLOBAL double **** StgFastPot
Definition neBEM.h:462

◆ neBEMTimeElapsed()

INTFACEGLOBAL double neBEMTimeElapsed ( clock_t t0,
clock_t t1 )

Definition at line 3233 of file neBEMInterface.c.

3233 {
3234 double elapsedTime = ((double)(t1 - t0)) / CLOCKS_PER_SEC;
3235 printf("neBEMV%s TimeElapsed ===> %lg seconds ", neBEMVersion, elapsedTime);
3236
3237 return (elapsedTime);
3238}

Referenced by ComputeSolution(), InitialConditions(), InvertMatrix(), neBEMBoundaryInitialConditions(), neBEMDiscretize(), neBEMPrepareWeightingField(), neBEMReadGeometry(), and neBEMSolve().

◆ neBEMVolumeCharge()

INTFACEGLOBAL double neBEMVolumeCharge ( int volume)

Definition at line 2639 of file neBEMInterface.c.

2639 {
2640 // Initialise the sum
2641 double sumcharge = 0.0;
2642
2643 // Loop over all elements
2644 for (int elem = 1; elem <= NbElements; ++elem) {
2645 // Find the primitive number for the element
2646 int prim = (EleArr + elem - 1)->PrimitiveNb;
2647
2648 // Find out to which volume this belongs to
2649 int volref = VolRef1[prim];
2650
2651 // Skip the rest if the volume is not right
2652 if (volref + 1 != volume) {
2653 continue;
2654 }
2655
2656 // Calculate the periodic weight of the primitive
2657 int rptCnt = 0;
2658 if (PeriodicInX[prim] || PeriodicInY[prim] || PeriodicInZ[prim]) {
2659 for (int xrpt = -PeriodicInX[prim]; xrpt <= PeriodicInX[prim]; ++xrpt)
2660 for (int yrpt = -PeriodicInY[prim]; yrpt <= PeriodicInY[prim]; ++yrpt)
2661 for (int zrpt = -PeriodicInZ[prim]; zrpt <= PeriodicInZ[prim];
2662 ++zrpt) {
2663 if ((xrpt == 0) && (yrpt == 0) && (zrpt == 0))
2664 continue;
2665 else
2666 ++rptCnt;
2667 }
2668 } else {
2669 rptCnt = 1;
2670 }
2671
2672 // Add the charge
2673 // printf("Element: %d, volume: %d, charge: %g\n", elem, volref,
2674 // (EleArr+elem-1)->Solution * (EleArr+elem-1)->G.dA);
2675 sumcharge +=
2676 rptCnt * (EleArr + elem - 1)->Solution * (EleArr + elem - 1)->G.dA;
2677 } // loop over elements
2678
2679 // Return the result
2680 // printf("Charge on volume %d: %g C\n", volume, sumcharge);
2681 return sumcharge;
2682} // end of neBEMVolumeCharge
neBEMGLOBAL double * Solution
Definition neBEM.h:197

◆ neBEMVolumeDescription()

INTFACEGLOBAL int neBEMVolumeDescription ( int ivol,
int * shape,
int * material,
double * epsilon,
double * potential,
double * charge,
int * boundarytype )

◆ neBEMVolumePoint()

INTFACEGLOBAL int neBEMVolumePoint ( double x,
double y,
double z )

◆ neBEMVolumePrimitives()

INTFACEGLOBAL void neBEMVolumePrimitives ( int volume,
int * nprim,
int primlist[] )

◆ neBEMWeightingField()

INTFACEGLOBAL double neBEMWeightingField ( Point3D * point,
Vector3D * field,
int IdWtField )

Definition at line 2605 of file neBEMInterface.c.

2605 {
2606 double potential;
2607
2608 if (neBEMState < 9) {
2609 printf("neBEMWeightingField cannot be called before reaching state 9.\n");
2610 return (-1);
2611 }
2612
2613 if (OptFixedWtField[IdWtField]) {
2614 // minimum computation, too restricted! Does not even consider variation
2615 // through IdWtField
2616 potential = FixedWtPotential[IdWtField];
2617 field->X = FixedWtFieldX[IdWtField];
2618 field->Y = FixedWtFieldY[IdWtField];
2619 field->Z = FixedWtFieldZ[IdWtField];
2620 } else if (OptWtFldFastVol[IdWtField]) {
2621 // bit more computation, lot more flexibility
2622 // Note: this is not the Create or Read option
2623 int fstatus = WtFldFastPFAtPoint(point, &potential, field, IdWtField);
2624 if (fstatus != 0) {
2625 neBEMMessage("neBEMWeightingField - WtFldFastPFAtPoint");
2626 return DBL_MAX;
2627 }
2628 } else {
2629 int fstatus = WtFldPFAtPoint(point, &potential, field, IdWtField);
2630 if (fstatus != 0) {
2631 neBEMMessage("neBEMWeightingField - WtFldPFAtPoint");
2632 return DBL_MAX;
2633 }
2634 }
2635
2636 return potential;
2637} // neBEMWeightingField ends
int WtFldPFAtPoint(Point3D *globalP, double *Potential, Vector3D *globalF, int IdWtField)
int WtFldFastPFAtPoint(Point3D *globalP, double *Potential, Vector3D *globalF, int IdWtField)
double Z
Definition Vector.h:31
double Y
Definition Vector.h:30
double X
Definition Vector.h:29

◆ ReadElements()

INTFACEGLOBAL int ReadElements ( void )

Definition at line 3108 of file neBEMInterface.c.

3108 {
3109 char ElementFile[256];
3110 strcpy(ElementFile, MeshOutDir);
3111 strcat(ElementFile, "/Elements/StoreElems.out");
3112
3113 FILE *fStrEle = fopen(ElementFile, "r");
3114 if (fStrEle == NULL) {
3115 neBEMMessage("ReadElements - Could not open file to read elements");
3116 return -1;
3117 }
3118
3119 fscanf(fStrEle, "%d %d\n", &NbSurfs, &NbWires);
3120
3121 for (int prim = 1; prim <= NbPrimitives; ++prim) {
3122 fscanf(fStrEle, "%d %d\n", &NbSurfSegX[prim], &NbSurfSegZ[prim]);
3123 fscanf(fStrEle, "%d\n", &NbWireSeg[prim]);
3124 }
3125
3126 fscanf(fStrEle, "%d\n", &NbElements);
3127
3128 if (neBEMState == 3) {
3129 if (EleArr) {
3130 Element *tmp = (Element *)realloc(EleArr, NbElements * sizeof(Element));
3131 if (tmp != NULL) {
3132 EleArr = tmp;
3133 EleCntr = 0;
3134 } else {
3135 free(EleArr);
3136 printf("neBEMDiscretize: Re-allocating EleArr failed.\n");
3137 fclose(fStrEle);
3138 return (1);
3139 }
3140 printf("neBEMDiscretize: Re-allocated EleArr.\n");
3141 } // if EleArr => re-allocation
3142 else {
3143 EleArr = (Element *)malloc(NbElements * sizeof(Element));
3144 if (EleArr == NULL) {
3145 neBEMMessage("neBEMDiscretize - EleArr malloc");
3146 return -1;
3147 }
3148 } // else EleArr => fresh allocation
3149 } else {
3150 neBEMMessage("neBEMDiscretize - EleArr malloc; neBEMState mismatch!");
3151 return -1;
3152 } // else neBEMState == 3
3153
3154 for (int ele = 1; ele <= NbElements; ++ele) {
3155 fscanf(fStrEle, "%hd %d %d %d %d\n", &(EleArr + ele - 1)->DeviceNb,
3156 &(EleArr + ele - 1)->ComponentNb, &(EleArr + ele - 1)->PrimitiveNb,
3157 &(EleArr + ele - 1)->InterfaceId, &(EleArr + ele - 1)->Id);
3158 fscanf(fStrEle, "%hd %le %le %le %le %le %le\n",
3159 &(EleArr + ele - 1)->G.Type, &(EleArr + ele - 1)->G.Origin.X,
3160 &(EleArr + ele - 1)->G.Origin.Y, &(EleArr + ele - 1)->G.Origin.Z,
3161 &(EleArr + ele - 1)->G.LX, &(EleArr + ele - 1)->G.LZ,
3162 &(EleArr + ele - 1)->G.dA);
3163 fscanf(fStrEle, "%le %le %le\n", &(EleArr + ele - 1)->G.DC.XUnit.X,
3164 &(EleArr + ele - 1)->G.DC.XUnit.Y,
3165 &(EleArr + ele - 1)->G.DC.XUnit.Z);
3166 fscanf(fStrEle, "%le %le %le\n", &(EleArr + ele - 1)->G.DC.YUnit.X,
3167 &(EleArr + ele - 1)->G.DC.YUnit.Y,
3168 &(EleArr + ele - 1)->G.DC.YUnit.Z);
3169 fscanf(fStrEle, "%le %le %le\n", &(EleArr + ele - 1)->G.DC.ZUnit.X,
3170 &(EleArr + ele - 1)->G.DC.ZUnit.Y,
3171 &(EleArr + ele - 1)->G.DC.ZUnit.Z);
3172 fscanf(fStrEle, "%hd %le\n", &(EleArr + ele - 1)->E.Type,
3173 &(EleArr + ele - 1)->E.Lambda);
3174 fscanf(fStrEle, "%hd %le %le %le %le\n", &(EleArr + ele - 1)->BC.NbOfBCs,
3175 &(EleArr + ele - 1)->BC.CollPt.X, &(EleArr + ele - 1)->BC.CollPt.Y,
3176 &(EleArr + ele - 1)->BC.CollPt.Z, &(EleArr + ele - 1)->BC.Value);
3177 fscanf(fStrEle, "%le %le\n", &(EleArr + ele - 1)->Solution,
3178 &(EleArr + ele - 1)->Assigned);
3179 }
3180
3181 fscanf(fStrEle, "%d %d %d %d\n", &NbPointsKnCh, &NbLinesKnCh, &NbAreasKnCh,
3182 &NbVolumesKnCh);
3183
3184 for (int pt = 1; pt <= NbPointsKnCh; ++pt) {
3185 fscanf(fStrEle, "%d %le\n", &(PointKnChArr + pt - 1)->Nb,
3186 &(PointKnChArr + pt - 1)->Assigned);
3187 fscanf(fStrEle, "%le %le %le\n", &(PointKnChArr + pt - 1)->P.X,
3188 &(PointKnChArr + pt - 1)->P.Y, &(PointKnChArr + pt - 1)->P.Z);
3189 }
3190
3191 for (int line = 1; line <= NbLinesKnCh; ++line) {
3192 fscanf(fStrEle, "%d %le %le\n", &(LineKnChArr + line - 1)->Nb,
3193 &(LineKnChArr + line - 1)->Radius,
3194 &(LineKnChArr + line - 1)->Assigned);
3195 fscanf(fStrEle, "%le %le %le\n", &(LineKnChArr + line - 1)->Start.X,
3196 &(LineKnChArr + line - 1)->Start.Y,
3197 &(LineKnChArr + line - 1)->Start.Z);
3198 fscanf(fStrEle, "%le %le %le\n", &(LineKnChArr + line - 1)->Stop.X,
3199 &(LineKnChArr + line - 1)->Stop.Y,
3200 &(LineKnChArr + line - 1)->Stop.Z);
3201 }
3202
3203 for (int area = 1; area <= NbAreasKnCh; ++area) {
3204 fscanf(fStrEle, "%d %d %le\n", &(AreaKnChArr + area - 1)->Nb,
3205 &(AreaKnChArr + area - 1)->NbVertices,
3206 &(AreaKnChArr + area - 1)->Assigned);
3207 for (int vert = 1; vert <= (AreaKnChArr + area - 1)->NbVertices; ++vert) {
3208 fscanf(fStrEle, "%le %le %le\n",
3209 &(AreaKnChArr + area - 1)->Vertex[vert].X,
3210 &(AreaKnChArr + area - 1)->Vertex[vert].Y,
3211 &(AreaKnChArr + area - 1)->Vertex[vert].Z);
3212 }
3213 }
3214
3215 for (int vol = 1; vol <= NbVolumesKnCh; ++vol) {
3216 fscanf(fStrEle, "%d %d %le\n", &(VolumeKnChArr + vol - 1)->Nb,
3217 &(VolumeKnChArr + vol - 1)->NbVertices,
3218 &(VolumeKnChArr + vol - 1)->Assigned);
3219 for (int vert = 1; vert <= (VolumeKnChArr + vol - 1)->NbVertices; ++vert) {
3220 fscanf(fStrEle, "%le %le %le\n",
3221 &(VolumeKnChArr + vol - 1)->Vertex[vert].X,
3222 &(VolumeKnChArr + vol - 1)->Vertex[vert].Y,
3223 &(VolumeKnChArr + vol - 1)->Vertex[vert].Z);
3224 }
3225 }
3226
3227 fclose(fStrEle);
3228
3229 return 0;
3230} // ReadElements ends
neBEMGLOBAL PointKnCh * PointKnChArr
Definition neBEM.h:253
neBEMGLOBAL VolumeKnCh * VolumeKnChArr
Definition neBEM.h:288
neBEMGLOBAL int NbPointsKnCh
Definition neBEM.h:244
neBEMGLOBAL AreaKnCh * AreaKnChArr
Definition neBEM.h:276
neBEMGLOBAL int NbLinesKnCh
Definition neBEM.h:244
neBEMGLOBAL int NbVolumesKnCh
Definition neBEM.h:244
neBEMGLOBAL int NbAreasKnCh
Definition neBEM.h:244
neBEMGLOBAL LineKnCh * LineKnChArr
Definition neBEM.h:264

Referenced by neBEMDiscretize().

◆ ReadInitFile()

INTFACEGLOBAL int ReadInitFile ( char filename[])

◆ ReadPrimitives()

INTFACEGLOBAL int ReadPrimitives ( void )

Definition at line 3004 of file neBEMInterface.c.

3004 {
3005 int dbgFn = 0;
3006
3007 char PrimitiveFile[256];
3008
3009 strcpy(PrimitiveFile, ModelOutDir);
3010 strcat(PrimitiveFile, "/Primitives/StorePrims.out");
3011
3012 FILE *fStrPrm = fopen(PrimitiveFile, "r");
3013 if (fStrPrm == NULL) {
3014 neBEMMessage("ReadPrimitives - Could not open file to read primitives");
3015 return -1;
3016 }
3017
3018 fscanf(fStrPrm, "%d %d\n", &NbVolumes, &VolMax);
3019 fscanf(fStrPrm, "%d\n", &NbPrimitives);
3020 fscanf(fStrPrm, "%d\n", &MaxNbVertices);
3021
3022 // assign neBEMState and allocate memory
3023 neBEMState = 2;
3032 Radius = dvector(1, NbPrimitives); // can lead to a little memory misuse
3037 NbWireSeg = ivector(1, NbPrimitives); // little memory misuse
3054
3055 for (int prim = 1; prim <= NbPrimitives; ++prim) {
3056 fscanf(fStrPrm, "%d\n", &PrimType[prim]);
3057 fscanf(fStrPrm, "%d\n", &InterfaceType[prim]);
3058 fscanf(fStrPrm, "%d\n", &NbVertices[prim]);
3059
3060 for (int vert = 0; vert < NbVertices[prim]; ++vert) {
3061 fscanf(fStrPrm, "%le %le %le\n", &XVertex[prim][vert],
3062 &YVertex[prim][vert], &ZVertex[prim][vert]);
3063 } // vert loop
3064
3065 fscanf(fStrPrm, "%le %le %le\n", &XNorm[prim], &YNorm[prim], &ZNorm[prim]);
3066 fscanf(fStrPrm, "%le\n", &Radius[prim]);
3067
3068 fscanf(fStrPrm, "%le %le %le %le %le\n", &Epsilon1[prim], &Epsilon2[prim],
3069 &Lambda[prim], &ApplPot[prim], &ApplCh[prim]);
3070
3071 fscanf(fStrPrm, "%d %d\n", &VolRef1[prim], &VolRef2[prim]);
3072
3073 fscanf(fStrPrm, "%d %d %d\n", &PeriodicTypeX[prim], &PeriodicTypeY[prim],
3074 &PeriodicTypeZ[prim]);
3075 fscanf(fStrPrm, "%d %d %d\n", &PeriodicInX[prim], &PeriodicInY[prim],
3076 &PeriodicInZ[prim]);
3077 fscanf(fStrPrm, "%le %le %le\n", &XPeriod[prim], &YPeriod[prim],
3078 &ZPeriod[prim]);
3079 fscanf(fStrPrm, "%le %le %le\n", &MirrorDistXFromOrigin[prim],
3081 } // prim loop
3082
3083 volRef = ivector(0, VolMax);
3084 volShape = ivector(0, VolMax);
3088 volCharge = dvector(0, VolMax);
3090 for (int volref = 0; volref <= VolMax; ++volref) {
3091 neBEMVolumeDescription(volref, &volShape[volref], &volMaterial[volref],
3092 &volEpsilon[volref], &volPotential[volref],
3093 &volCharge[volref], &volBoundaryType[volref]);
3094 if (dbgFn) {
3095 printf("volref: %d\n", volref);
3096 printf("shape: %d, material: %d\n", volShape[volref],
3097 volMaterial[volref]);
3098 printf("eps: %lg, pot: %lg\n", volEpsilon[volref], volPotential[volref]);
3099 printf("q: %lg, type: %d\n", volCharge[volref], volBoundaryType[volref]);
3100 }
3101 } // volume loop
3102
3103 fclose(fStrPrm);
3104
3105 return 0;
3106} // ReadPrimitives ends
neBEMGLOBAL int NbVolumes
Definition neBEM.h:63

Referenced by neBEMReadGeometry().

◆ WriteElements()

INTFACEGLOBAL int WriteElements ( void )

Definition at line 2910 of file neBEMInterface.c.

2910 {
2911 char ElementFile[256];
2912
2913 strcpy(ElementFile, MeshOutDir);
2914 strcat(ElementFile, "/Elements/StoreElems.out");
2915
2916 FILE *fStrEle = fopen(ElementFile, "w");
2917 if (fStrEle == NULL) {
2918 neBEMMessage("WriteElements - Could not create file to store elements");
2919 return -1;
2920 }
2921
2922 fprintf(fStrEle, "%d %d\n", NbSurfs, NbWires);
2923
2924 for (int prim = 1; prim <= NbPrimitives; ++prim) {
2925 fprintf(fStrEle, "%d %d\n", NbSurfSegX[prim], NbSurfSegZ[prim]);
2926 fprintf(fStrEle, "%d\n", NbWireSeg[prim]);
2927 }
2928
2929 fprintf(fStrEle, "%d\n", NbElements);
2930
2931 for (int ele = 1; ele <= NbElements; ++ele) {
2932 fprintf(fStrEle, "%d %d %d %d %d\n", (EleArr + ele - 1)->DeviceNb,
2933 (EleArr + ele - 1)->ComponentNb, (EleArr + ele - 1)->PrimitiveNb,
2934 (EleArr + ele - 1)->InterfaceId, (EleArr + ele - 1)->Id);
2935 fprintf(fStrEle, "%d %le %le %le %le %le %le\n", (EleArr + ele - 1)->G.Type,
2936 (EleArr + ele - 1)->G.Origin.X, (EleArr + ele - 1)->G.Origin.Y,
2937 (EleArr + ele - 1)->G.Origin.Z, (EleArr + ele - 1)->G.LX,
2938 (EleArr + ele - 1)->G.LZ, (EleArr + ele - 1)->G.dA);
2939 fprintf(fStrEle, "%le %le %le\n", (EleArr + ele - 1)->G.DC.XUnit.X,
2940 (EleArr + ele - 1)->G.DC.XUnit.Y, (EleArr + ele - 1)->G.DC.XUnit.Z);
2941 fprintf(fStrEle, "%le %le %le\n", (EleArr + ele - 1)->G.DC.YUnit.X,
2942 (EleArr + ele - 1)->G.DC.YUnit.Y, (EleArr + ele - 1)->G.DC.YUnit.Z);
2943 fprintf(fStrEle, "%le %le %le\n", (EleArr + ele - 1)->G.DC.ZUnit.X,
2944 (EleArr + ele - 1)->G.DC.ZUnit.Y, (EleArr + ele - 1)->G.DC.ZUnit.Z);
2945 fprintf(fStrEle, "%d %le\n", (EleArr + ele - 1)->E.Type,
2946 (EleArr + ele - 1)->E.Lambda);
2947 fprintf(fStrEle, "%d %le %le %le %le\n", (EleArr + ele - 1)->BC.NbOfBCs,
2948 (EleArr + ele - 1)->BC.CollPt.X, (EleArr + ele - 1)->BC.CollPt.Y,
2949 (EleArr + ele - 1)->BC.CollPt.Z, (EleArr + ele - 1)->BC.Value);
2950 fprintf(fStrEle, "%le %le\n", (EleArr + ele - 1)->Solution,
2951 (EleArr + ele - 1)->Assigned);
2952 }
2953
2954 fprintf(fStrEle, "%d %d %d %d\n", NbPointsKnCh, NbLinesKnCh, NbAreasKnCh,
2956
2957 for (int pt = 1; pt <= NbPointsKnCh; ++pt) {
2958 fprintf(fStrEle, "%d %le\n", (PointKnChArr + pt - 1)->Nb,
2959 (PointKnChArr + pt - 1)->Assigned);
2960 fprintf(fStrEle, "%le %le %le\n", (PointKnChArr + pt - 1)->P.X,
2961 (PointKnChArr + pt - 1)->P.Y, (PointKnChArr + pt - 1)->P.Z);
2962 }
2963
2964 for (int line = 1; line <= NbLinesKnCh; ++line) {
2965 fprintf(fStrEle, "%d %le %le\n", (LineKnChArr + line - 1)->Nb,
2966 (LineKnChArr + line - 1)->Radius,
2967 (LineKnChArr + line - 1)->Assigned);
2968 fprintf(fStrEle, "%le %le %le\n", (LineKnChArr + line - 1)->Start.X,
2969 (LineKnChArr + line - 1)->Start.Y,
2970 (LineKnChArr + line - 1)->Start.Z);
2971 fprintf(fStrEle, "%le %le %le\n", (LineKnChArr + line - 1)->Stop.X,
2972 (LineKnChArr + line - 1)->Stop.Y, (LineKnChArr + line - 1)->Stop.Z);
2973 }
2974
2975 for (int area = 1; area <= NbAreasKnCh; ++area) {
2976 fprintf(fStrEle, "%d %d %le\n", (AreaKnChArr + area - 1)->Nb,
2977 (AreaKnChArr + area - 1)->NbVertices,
2978 (AreaKnChArr + area - 1)->Assigned);
2979 for (int vert = 1; vert <= (AreaKnChArr + area - 1)->NbVertices; ++vert) {
2980 fprintf(fStrEle, "%le %le %le\n",
2981 (AreaKnChArr + area - 1)->Vertex[vert].X,
2982 (AreaKnChArr + area - 1)->Vertex[vert].Y,
2983 (AreaKnChArr + area - 1)->Vertex[vert].Z);
2984 }
2985 }
2986
2987 for (int vol = 1; vol <= NbVolumesKnCh; ++vol) {
2988 fprintf(fStrEle, "%d %d %le\n", (VolumeKnChArr + vol - 1)->Nb,
2989 (VolumeKnChArr + vol - 1)->NbVertices,
2990 (VolumeKnChArr + vol - 1)->Assigned);
2991 for (int vert = 1; vert <= (VolumeKnChArr + vol - 1)->NbVertices; ++vert) {
2992 fprintf(fStrEle, "%le %le %le\n",
2993 (VolumeKnChArr + vol - 1)->Vertex[vert].X,
2994 (VolumeKnChArr + vol - 1)->Vertex[vert].Y,
2995 (VolumeKnChArr + vol - 1)->Vertex[vert].Z);
2996 }
2997 }
2998
2999 fclose(fStrEle);
3000
3001 return 0;
3002} // WriteElements ends

Referenced by neBEMDiscretize().

◆ WritePrimitives()

INTFACEGLOBAL int WritePrimitives ( void )

Definition at line 2861 of file neBEMInterface.c.

2861 {
2862 char PrimitiveFile[256];
2863
2864 strcpy(PrimitiveFile, ModelOutDir);
2865 strcat(PrimitiveFile, "/Primitives/StorePrims.out");
2866
2867 FILE *fStrPrm = fopen(PrimitiveFile, "w");
2868 if (fStrPrm == NULL) {
2869 neBEMMessage("WritePrimitives - Could not create file to store primitives");
2870 return -1;
2871 }
2872
2873 fprintf(fStrPrm, "%d %d\n", NbVolumes, VolMax);
2874 fprintf(fStrPrm, "%d\n", NbPrimitives);
2875 fprintf(fStrPrm, "%d\n", MaxNbVertices);
2876
2877 for (int prim = 1; prim <= NbPrimitives; ++prim) {
2878 fprintf(fStrPrm, "%d\n", PrimType[prim]);
2879 fprintf(fStrPrm, "%d\n", InterfaceType[prim]);
2880 fprintf(fStrPrm, "%d\n", NbVertices[prim]);
2881
2882 for (int vert = 0; vert < NbVertices[prim]; ++vert) {
2883 fprintf(fStrPrm, "%le %le %le\n", XVertex[prim][vert],
2884 YVertex[prim][vert], ZVertex[prim][vert]);
2885 } // vert loop
2886
2887 fprintf(fStrPrm, "%le %le %le\n", XNorm[prim], YNorm[prim], ZNorm[prim]);
2888 fprintf(fStrPrm, "%le\n", Radius[prim]);
2889
2890 fprintf(fStrPrm, "%le %le %le %le %le\n", Epsilon1[prim], Epsilon2[prim],
2891 Lambda[prim], ApplPot[prim], ApplCh[prim]);
2892
2893 fprintf(fStrPrm, "%d %d\n", VolRef1[prim], VolRef2[prim]);
2894
2895 fprintf(fStrPrm, "%d %d %d\n", PeriodicTypeX[prim], PeriodicTypeY[prim],
2896 PeriodicTypeZ[prim]);
2897 fprintf(fStrPrm, "%d %d %d\n", PeriodicInX[prim], PeriodicInY[prim],
2898 PeriodicInZ[prim]);
2899 fprintf(fStrPrm, "%le %le %le\n", XPeriod[prim], YPeriod[prim],
2900 ZPeriod[prim]);
2901 fprintf(fStrPrm, "%le %le %le\n", MirrorDistXFromOrigin[prim],
2903 } // prim loop
2904
2905 fclose(fStrPrm);
2906
2907 return 0;
2908} // WritePrimitives ends

Referenced by neBEMReadGeometry().

Variable Documentation

◆ DeviceInputFile

INTFACEGLOBAL char DeviceInputFile[256]

Definition at line 45 of file neBEMInterface.h.

Referenced by neBEMInitialize(), neBEM::neBEMSetDefaults(), and neBEM::ReadInitFile().

◆ fgnuElem

INTFACEGLOBAL FILE * fgnuElem

Definition at line 55 of file neBEMInterface.h.

Referenced by DiscretizeRectangle(), DiscretizeTriangle(), and neBEMDiscretize().

◆ fgnuMesh

INTFACEGLOBAL FILE * fgnuMesh

Definition at line 55 of file neBEMInterface.h.

Referenced by DiscretizeRectangle(), DiscretizeTriangle(), and neBEMDiscretize().

◆ fgnuPrim

INTFACEGLOBAL FILE* fgnuPrim

◆ NbThreads

INTFACEGLOBAL int NbThreads

Definition at line 49 of file neBEMInterface.h.

Referenced by neBEMInitialize().

◆ neBEMPFCallCntr

INTFACEGLOBAL int neBEMPFCallCntr

Definition at line 109 of file neBEMInterface.h.

◆ neBEMState

◆ OptDeviceFile

INTFACEGLOBAL int OptDeviceFile

Definition at line 44 of file neBEMInterface.h.

Referenced by neBEMInitialize(), neBEM::neBEMSetDefaults(), and neBEM::ReadInitFile().

◆ OptElementFiles

◆ OptGnuplot

◆ OptGnuplotElements

◆ OptGnuplotPrimitives

◆ OptPrimitiveFiles

◆ OptPrintPrimaryDetails

INTFACEGLOBAL int OptPrintPrimaryDetails

◆ OptPrintVertexAndNormal

◆ OptPrintVolumeDetails

INTFACEGLOBAL int OptPrintVolumeDetails

◆ OptReuseDir

INTFACEGLOBAL int OptReuseDir

Definition at line 142 of file neBEMInterface.h.

Referenced by CreateDirStr(), neBEM::neBEMSetDefaults(), and neBEM::ReadInitFile().

◆ startClock

◆ stopClock