46 #include <Xyce_config.h>
58 #include <N_ERH_ErrorMgr.h>
59 #include <N_UTL_Diagnostic.h>
60 #include <N_UTL_ExtendedString.h>
61 #include <N_UTL_FeatureTest.h>
62 #include <N_UTL_Math.h>
65 typedef unsigned int UINT;
89 meshScaledFlag (false),
104 iRecentCellLookup(0),
107 meshFileName (
"internal"),
108 externalMeshFlag (false),
117 adjInfoAllocFlag(false),
118 sgplotLevel(sgplotLevel1),
119 useDefaultLabels(true)
134 meshFileName (right.meshFileName),
135 externalMeshFlag (right.externalMeshFlag),
142 xRatio (right.xRatio),
143 yRatio (right.yRatio),
145 meshScaledFlag (right.meshScaledFlag),
147 invVol (right.invVol),
148 surfArea (right.surfArea),
149 circum (right.circum),
150 invCircum (right.invCircum),
152 numNodes (right.numNodes),
153 numEdges (right.numEdges),
154 numCells (right.numCells),
155 numLabels (right.numLabels),
156 numRegLabels (right.numRegLabels),
157 numBndryNodes (right.numBndryNodes),
158 maxNodeNN (right.maxNodeNN),
159 iRecentCellLookup(right.iRecentCellLookup),
160 cylGeom (right.cylGeom),
161 dopingSet (right.dopingSet),
162 mNodeVector (right.mNodeVector),
163 mEdgeVector (right.mEdgeVector),
164 mCellVector (right.mCellVector),
165 mLabelVector (right.mLabelVector),
166 dopingVector (right.dopingVector),
167 xVector (right.xVector),
168 yVector (right.yVector),
169 visitCellFlagVec (right.visitCellFlagVec),
170 mLabelMap (right.mLabelMap),
173 devOptions_ (right.devOptions_),
174 afVisitedVec (right.afVisitedVec),
175 adjInfoAllocFlag (right.adjInfoAllocFlag),
176 sgplotLevel (right.sgplotLevel),
189 for (i=0;i<
ixMax+10;++i)
193 for (j=0;j<
iyMax+10;++j)
207 for (j=0;j<numNodes+10;++j)
217 for (i=0;i<
ixMax+10;++i)
220 for (j=0;j<
iyMax+10;++j)
302 for (i=0;i<
ixMax+10;++i)
306 for (j=0;j<
iyMax+10;++j)
320 for (j=0;j<numNodes+10;++j)
330 for (i=0;i<
ixMax+10;++i)
333 for (j=0;j<
iyMax+10;++j)
366 for (i=0;i<
ixMax+10;++i)
384 for (i=0;i<
ixMax+10;++i)
416 bool bsuccess =
true;
430 bsuccess = bsuccess && tmpBool;
438 bsuccess = bsuccess && tmpBool;
442 if (DEBUG_DEVICE && isActive(Diag::DEVICE_DUMP_VECTORS))
466 FILE *nFile = fopen(meshFileName_tmp.c_str(),
"r");
470 std::string msg(
"PDE_2DMesh::readSGFMeshFile - ");
471 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg + meshFileName_tmp +
476 fread(&meshhead,
sizeof(
MESHHEAD),1,nFile);
480 fseek(nFile, lOffset, SEEK_CUR);
484 fread(&cLabel,
sizeof(UINT),1,nFile);
489 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
490 Xyce::dout() <<
"About to read label lists: cLabel = " << cLabel << std::endl;
492 for(i = 0; i < cLabel; ++i)
497 fread(&xlatlabel,
sizeof(
XLATLABEL),1,nFile);
503 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
505 Xyce::dout() <<
"i = " << i ;
506 Xyce::dout() <<
" iIndex = " << xLabel.
iIndex;
507 Xyce::dout() <<
" uType = " << xLabel.
uType;
508 Xyce::dout() <<
" cNode = " << xLabel.
cNode;
509 Xyce::dout() <<
" label name = " << xLabel.
name << std::endl;
514 for (j=0;j<xlatlabel.
cNode; ++j)
517 fread(&au,
sizeof(UINT),1,nFile);
523 ExtendedString tmpName = xLabel.
name;
540 fread(&cArray,
sizeof(UINT),1,nFile);
541 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
542 Xyce::dout() <<
"About to read in the arrays. cArray = " << cArray << std::endl;
546 for(i = 0; i < 2; ++i)
550 ExtendedString tmpName(szArrayName);
554 Xyce::dout() <<
"i=" <<i<<
" name = " << tmpName << std::endl;
560 for (j=0;j<meshhead.
cNode; ++j)
562 fread(&xtmp,
sizeof(
double),1,nFile);
566 else if (tmpName ==
"Y")
569 for (j=0;j<meshhead.
cNode; ++j)
571 fread(&xtmp,
sizeof(
double),1,nFile);
577 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
579 Xyce::dout() <<
"Done reading x and y arrays.";
580 Xyce::dout() <<
" Reading the others, if they exist." << std::endl;
586 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
587 Xyce::dout() <<
"reading extra arrays..." << std::endl;
588 for(i = 2; i < meshhead.
cArray; ++i)
592 ExtendedString tmpName(szArrayName);
597 for (j=0;j<meshhead.
cNode; ++j)
599 fread(&xtmp,
sizeof(
double),1,nFile);
606 for (j=0;j<meshhead.
cNode; ++j)
607 fread(&xtmp,
sizeof(
double),1,nFile);
614 fread(&cNodes,
sizeof(UINT),1,nFile);
621 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
622 Xyce::dout() <<
"About to read the nodes. cNodes = " << cNodes << std::endl;
624 for (i=0;i<cNodes;++i)
627 fread(&sgfNode,
sizeof(
NODE),1,nFile);
637 fread(&cEdge,
sizeof(UINT),1,nFile);
641 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
642 Xyce::dout() <<
"About to read the edges. cEdge = " << cEdge << std::endl;
644 for (i=0; i< cEdge; ++i)
647 fread(&sgfEdge,
sizeof(
EDGE),1,nFile);
649 int inode1 = sgfEdge.
inodeA;
650 int inode2 = sgfEdge.
inodeB;
669 fread(&cTriangle,
sizeof(UINT),1,nFile);
673 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
674 Xyce::dout() <<
"About to read the cells. numCells = " <<
numCells << std::endl;
675 for (i=0;i<cTriangle;++i)
678 fread(&Tri,
sizeof(
TRI),1,nFile);
698 fread(&cAdj,
sizeof(UINT),1,nFile);
701 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
702 Xyce::dout() <<
"About to read the adjacency info. cAdj = " << cAdj << std::endl;
704 double rDistScale = 1.0;
705 double X0_1 = rDistScale;
706 double X0_2 = rDistScale * X0_1;
707 double X0_3 = rDistScale * X0_2;
709 double ScaleILEN, ScaleAREA, ScaleELEN = X0_1;
712 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
714 if (meshhead.
fCylGeom) Xyce::dout() <<
"Cylindrical Geometry\n\n";
715 else Xyce::dout() <<
"Cartesian Geometry\n\n";
741 for(i = 0; i < cAdj; ++i)
744 fread(&inode,
sizeof(
int),1,nFile);
748 nodeInfo.
Area /= ScaleAREA;
757 for (j=0;j<cNeighbor;++j)
759 fread( &EdgeInfo,
sizeof(
EDGEINFO),1,nFile);
760 mNodeVector[inode].edgeInfoVector.push_back(EdgeInfo);
763 for(j = 0; j < cNeighbor; ++j)
768 mNodeVector[inode].edgeInfoVector[j].ilen /= ScaleILEN;
769 mNodeVector[inode].edgeInfoVector[j].elen /= ScaleELEN;
770 mNodeVector[inode].edgeInfoVector[j].Area1 /= ScaleAREA;
771 mNodeVector[inode].edgeInfoVector[j].Area2 /= ScaleAREA;
773 int iedge =
mNodeVector[inode].edgeInfoVector[j].iedge;
806 FILE *nFile = fopen(meshFileName_tmp.c_str(),
"w");
808 strcpy(meshhead.
szLogo,
"SGFramework Mesh File Version 1.0\n\x1a");
809 strcpy(meshhead.
szSign,
"@~!__MESH__!~@");
825 fwrite( &meshhead,
sizeof(
MESHHEAD), 1, nFile);
829 fwrite( &meshhead.
cConstant,
sizeof(UINT), 1, nFile);
832 fwrite( &meshhead.
cLabel,
sizeof(UINT), 1, nFile);
833 for (i=0;i<meshhead.
cLabel;++i)
841 fwrite(&xlabel,
sizeof(
XLATLABEL) ,1,nFile);
845 for (j=0;j<xlabel.
cNode;++j)
848 fwrite(&istuf,
sizeof(UINT), 1, nFile);
859 fwrite( &cArray,
sizeof(UINT),1,nFile);
861 strcpy(szCoord1,
"X");
862 fwrite( szCoord1, (
LEN_IDENT+1), 1, nFile);
866 fwrite( &(
xVector[i]),
sizeof(
double), 1, nFile);
870 strcpy(szCoord2,
"Y");
871 fwrite( szCoord2, (
LEN_IDENT+1), 1, nFile);
874 fwrite( &(
yVector[i]),
sizeof(
double), 1, nFile);
880 fwrite( &meshhead.
cNode,
sizeof(UINT), 1, nFile);
881 for (i=0;i<meshhead.
cNode;++i)
885 fwrite(&n1,
sizeof(
NODE), 1, nFile);
889 fwrite( &meshhead.
cEdge,
sizeof(UINT), 1, nFile);
890 for (i=0;i<meshhead.
cEdge;++i)
896 fwrite( &e1,
sizeof(
EDGE), 1, nFile);
900 fwrite(&meshhead.
cTriangle,
sizeof(UINT),1,nFile);
910 if (tmp < 0) t1.
uLabel = -1u;
911 else t1.
uLabel =
static_cast<unsigned int>(tmp);
923 fwrite(&t1,
sizeof(
TRI), 1, nFile);
929 fwrite(&numNodes,
sizeof(UINT), 1, nFile);
933 fwrite(&inode,
sizeof(UINT),1,nFile);
945 fwrite(&edgeinfo,
sizeof(
EDGEINFO),1,nFile);
975 std::string & outputMeshFileName,
976 std::map<std::string,PDE_2DElectrode*> & elMap,
979 bool bsuccess =
true;
984 externalMeshFlag =
false;
986 meshFileName = outputMeshFileName;
988 bsuccess = setupInternalMesh (nx,ny,xlength,ylength);
993 if ( !(elMap.empty()) )
995 tmpBool = errorCheckElectrodes (numElectrodes, elMap);
996 bsuccess = bsuccess && tmpBool;
999 if ( useDefaultLabels )
1001 tmpBool = setupDefaultLabels(numElectrodes);
1002 bsuccess = bsuccess && tmpBool;
1006 tmpBool = setupInternalLabels(numElectrodes, elMap);
1007 bsuccess = bsuccess && tmpBool;
1013 tmpBool = cellNodes();
1014 bsuccess = bsuccess && tmpBool;
1019 tmpBool = setupGeometry ();
1020 bsuccess = bsuccess && tmpBool;
1022 visitCellFlagVec.resize(numCells,0);
1024 if (DEBUG_DEVICE && isActive(Diag::DEVICE_DUMP_VECTORS))
1029 if (sgplotLevel > 0)
1031 tmpBool = writeSGFMeshFile (outputMeshFileName);
1032 bsuccess = bsuccess && tmpBool;
1057 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1059 Xyce::dout() <<
"In PDE_2DMesh:resizeMesh." << std::endl;
1065 xRatio = xlength/(old_xlength);
1066 yRatio = ylength/(old_ylength);
1069 xMax = xMin + xlength;
1070 yMax = yMin + ylength;
1072 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1074 Xyce::dout() <<
" xMax = " <<
xMax << std::endl;
1075 Xyce::dout() <<
" yMax = " <<
yMax << std::endl;
1093 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1095 Xyce::dout() <<
"\txVec["<<i<<
"] = " <<
xVector[i];
1096 Xyce::dout() <<
"\tyVec["<<i<<
"] = " <<
yVector[i] << std::endl;
1103 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1105 Xyce::dout() <<
"Done with PDE_2DMesh:resizeMesh." << std::endl;
1131 int nx,
int ny,
double xlength,
double ylength)
1141 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1142 Xyce::dout() <<
"In setupInternalMesh"<<std::endl;
1148 dy =
yMax/(
static_cast<double>(iyMax-1));
1152 for (i=0;i<
ixMax+10;++i)
1156 for (j=0;j<iyMax+10;++j)
1166 for (i=0;i<
ixMax;++i)
1168 for (j=0;j<
iyMax;++j)
1171 n1.
x =
dx*(
static_cast<double>(i));
1172 n1.
y =
dy*(
static_cast<double>(j));
1177 if (i==0 || j==0 || i==ixMax-1 || j==iyMax-1)
1190 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1192 Xyce::dout() <<
"\nDone with Node vector" << std::endl;
1200 for (j=0;j<numNodes+10;++j)
1209 for (i=0;i<
ixMax;++i)
1211 for (j=0;j<
iyMax;++j)
1239 Xyce::dout() <<
" edge1.inodeA = " << edge1.
inodeA;
1240 Xyce::dout() <<
" edge1.inodeB = " << edge1.
inodeB <<std::endl;
1242 Report::DevelFatal() <<
"Failed on edge1";
1278 Xyce::dout() <<
" edge2.inodeA = " << edge2.
inodeA;
1279 Xyce::dout() <<
" edge2.inodeB = " << edge2.
inodeB <<std::endl;
1281 Report::DevelFatal() <<
"Failed on edge2";
1294 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1296 Xyce::dout() <<
"Done with Edge vector" << std::endl;
1302 for (i=0;i<ixMax+10;++i)
1305 for (j=0;j<iyMax+10;++j)
1309 for (i=1; i<
ixMax; ++i)
1311 for (j=1;j<
iyMax;++j)
1325 int inodeA, inodeB, inodeC, inodeD;
1353 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1355 Xyce::dout() <<
"Done with Cell vector" << std::endl;
1361 for (i=1; i<
ixMax; ++i)
1363 for (j=1;j<
iyMax;++j)
1372 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1374 Xyce::dout() <<
"Done with Cell neighbors." << std::endl;
1398 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1400 Xyce::dout() <<
"Done with setupInternalMesh\n";
1427 Xyce::dout() <<
"In PDE_2DMesh::setupInternalAdjacencyInfo." << std::endl;
1434 int inodeA = edgeTmp.
inodeA;
1435 int inodeB = edgeTmp.
inodeB;
1454 edgeTmp.
ilen *= 0.5;
1458 edgeTmp.
Area2 = 0.0;
1466 Xyce::dout() <<
"About to do the edgeinfo:" << std::endl;
1469 for (i=0;i<
ixMax;++i)
1471 for (j=0;j<
iyMax;++j)
1478 if (i==0 || i==ixMax-1)
1483 if (j==0 || j==iyMax-1)
1497 eiTmp.
inode = nnTmp;
1498 eiTmp.
iedge = edgeTmp;
1501 mNodeVector[node].edgeInfoVector.push_back(eiTmp);
1509 eiTmp.
inode = nnTmp;
1510 eiTmp.
iedge = edgeTmp;
1513 mNodeVector[node].edgeInfoVector.push_back(eiTmp);
1521 eiTmp.
inode = nnTmp;
1522 eiTmp.
iedge = edgeTmp;
1525 mNodeVector[node].edgeInfoVector.push_back(eiTmp);
1533 eiTmp.
inode = nnTmp;
1534 eiTmp.
iedge = edgeTmp;
1537 mNodeVector[node].edgeInfoVector.push_back(eiTmp);
1546 Xyce::dout() <<
"Done doing the edgeinfo:" << std::endl;
1565 (
int numElectrodes, std::map<std::string,PDE_2DElectrode*> & elMap)
1567 bool bsuccess =
true;
1570 if (numElectrodes != elMap.size())
1573 std::string msg(
"Number of electrodes and number of nodes are not equal.\n");
1574 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
1585 bool allNotSet =
true;
1586 useDefaultLabels =
false;
1588 std::map<std::string, PDE_2DElectrode*>::iterator mapIter;
1589 std::map<std::string, PDE_2DElectrode*>::iterator mapStart = elMap.begin();
1590 std::map<std::string, PDE_2DElectrode*>::iterator mapEnd = elMap.end();
1592 for ( mapIter = mapStart; mapIter != mapEnd; ++mapIter )
1596 allSet = allSet && (el.
given(
"START") && el.
given(
"END") && el.
given(
"SIDE"));
1597 allNotSet = allNotSet &&
1601 if (!allSet && !allNotSet)
1604 std::string msg(
"Some electrodes have start, end and side specified,\nsome don't. ");
1605 msg +=
"Either specify start, end and side for\nall electrodes, or none.\n";
1606 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
1613 useDefaultLabels =
true;
1646 ExtendedString tmpName =
"SI";
1658 for (i=1;i<
ixMax-1;++i)
1660 for (j=1;j<iyMax-1;++j)
1668 tmpName = xLabel.
name;
1677 if (numberElectrodes==2)
1683 xLabel.
name =
"ANODE";
1692 for (i=0;i<
ixMax;++i)
1699 tmpName = xLabel.
name;
1704 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1706 Xyce::dout() <<
"Right before pushing back the ANODE label." << std::endl;
1709 cout <<
"Node: " << i <<
" = " << xLabel.
mNodeVector[i];
1718 xLabel.
name =
"CATHODE";
1727 for (i=0;i<
ixMax;++i)
1734 tmpName = xLabel.
name;
1739 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1741 Xyce::dout() <<
"Right before pushing back the CATHODE label." << std::endl;
1744 cout <<
"Node: " << i <<
" = " << xLabel.
mNodeVector[i];
1754 xLabel.
name =
"NOFLUX";
1757 xLabel.
cNode = 2*iyMax-2;
1763 for (j=1;j<iyMax-1;++j)
1770 for (j=1;j<iyMax-1;++j)
1777 tmpName = xLabel.
name;
1782 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1784 Xyce::dout() <<
"Right before pushing back the NOFLUX label." << std::endl;
1787 Xyce::dout() <<
"Node: " << i <<
" = " << xLabel.
mNodeVector[i];
1788 Xyce::dout() << std::endl;
1800 for (i=1;i<
ixMax;++i)
1811 for (i=1;i<
ixMax;++i)
1822 for (j=1;j<
iyMax;++j)
1833 for (j=1;j<
iyMax;++j)
1843 else if (numberElectrodes==3)
1870 int iB =
static_cast<int> (0.101 *
static_cast<double>(ixMax-1));
1871 int iC =
static_cast<int> (0.301 *
static_cast<double>(ixMax-1));
1872 int iD =
static_cast<int> (0.401 *
static_cast<double>(ixMax-1));
1873 int iE =
static_cast<int> (0.701 *
static_cast<double>(ixMax-1));
1874 int iF =
static_cast<int> (0.801 *
static_cast<double>(ixMax-1));
1881 xLabel.
name =
"EMITTER";
1884 xLabel.
cNode = iB-iA+1;
1890 for (i=iA;i<iB+1;++i)
1897 tmpName = xLabel.
name;
1905 xLabel.
name =
"BASE";
1908 xLabel.
cNode = iD-iC+1;
1914 for (i=iC;i<iD+1;++i)
1921 tmpName = xLabel.
name;
1929 xLabel.
name =
"COLLECTOR";
1932 xLabel.
cNode = iF-iE+1;
1938 for (i=iE;i<iF+1;++i)
1945 tmpName = xLabel.
name;
1960 xLabel.
name =
"NOFLUX";
1969 for (i=iB+1;i<iC;++i)
1976 for (i=iD+1;i<iE;++i)
1983 for (i=iF+1;i<iG;++i)
1991 for (j=0;j<iyMax-1;++j)
1999 for (j=0;j<iyMax-2;++j)
2007 for (i=0;i<ixMax-1;++i)
2016 tmpName = xLabel.
name;
2029 for (i=iA+1;i<iB+1;++i)
2040 for (i=iC+1;i<iD+1;++i)
2051 for (i=iE+1;i<iF+1;++i)
2063 for (i=iB+1;i<iC+1;++i)
2074 for (i=iD+1;i<iE+1;++i)
2085 for (i=iF+1;i<iG+1;++i)
2096 for (i=1;i<
ixMax;++i)
2107 for (j=1;j<
iyMax;++j)
2118 for (j=1;j<
iyMax;++j)
2129 else if (numberElectrodes==4)
2164 int iB =
static_cast<int> (0.101 *
static_cast<double>(ixMax-1));
2165 int iC =
static_cast<int> (0.151 *
static_cast<double>(ixMax-1));
2166 int iD =
static_cast<int> (0.851 *
static_cast<double>(ixMax-1));
2167 int iE =
static_cast<int> (0.901 *
static_cast<double>(ixMax-1));
2174 Xyce::dout() <<
"iA = "<< iA << std::endl;
2175 Xyce::dout() <<
"iB = "<< iB << std::endl;
2176 Xyce::dout() <<
"iC = "<< iC << std::endl;
2177 Xyce::dout() <<
"iD = "<< iD << std::endl;
2178 Xyce::dout() <<
"iE = "<< iE << std::endl;
2179 Xyce::dout() <<
"iF = "<< iF << std::endl;
2184 xLabel.
name =
"SOURCE";
2187 xLabel.
cNode = iB-iA+1;
2193 for (i=iA;i<iB+1;++i)
2200 tmpName = xLabel.
name;
2208 xLabel.
name =
"GATE";
2211 xLabel.
cNode = iD-iC+1;
2217 for (i=iC;i<iD+1;++i)
2224 tmpName = xLabel.
name;
2232 xLabel.
name =
"DRAIN";
2235 xLabel.
cNode = iF-iE+1;
2241 for (i=iE;i<iF+1;++i)
2248 tmpName = xLabel.
name;
2257 xLabel.
name =
"SUB";
2260 xLabel.
cNode = iF-iA+1;
2266 for (i=iA;i<iF+1;++i)
2273 tmpName = xLabel.
name;
2284 xLabel.
name =
"NOFLUX";
2287 xLabel.
cNode = (iC-iB-1)+(iE-iD-1)+(iyMax-1)+(iyMax-1);
2293 for (i=iB+1;i<iC;++i)
2300 for (i=iD+1;i<iE;++i)
2308 for (j=1;j<iyMax-1;++j)
2316 for (j=1;j<iyMax-1;++j)
2323 tmpName = xLabel.
name;
2335 for (i=iA+1;i<iB+1;++i)
2346 for (i=iC+1;i<iD+1;++i)
2357 for (i=iE+1;i<iF+1;++i)
2368 for (i=iA+1;i<iF+1;++i)
2379 for (i=iB+1;i<iC+1;++i)
2390 for (i=iD+1;i<iE+1;++i)
2401 for (j=1;j<
iyMax;++j)
2412 for (j=1;j<
iyMax;++j)
2426 Xyce::dout() <<
"Sorry, the internal mesh generator can't";
2427 Xyce::dout() <<
" handle anything greater than 4 electrodes." << std::endl;
2449 std::map<std::string,PDE_2DElectrode*> & elMap)
2456 ExtendedString tmpName =
"SI";
2468 for (i=1;i<
ixMax-1;++i)
2470 for (j=1;j<iyMax-1;++j)
2478 tmpName = xLabel.
name;
2486 std::vector<int> done;
2489 std::map<std::string, PDE_2DElectrode*>::iterator mapIter;
2490 std::map<std::string, PDE_2DElectrode*>::iterator mapStart =
2492 std::map<std::string, PDE_2DElectrode*>::iterator mapEnd =
2499 for ( mapIter = mapStart; mapIter != mapEnd; ++mapIter )
2505 if (el.
side ==
"top" || el.
side ==
"bottom")
2532 el.
iA =
static_cast<int> (start *
static_cast<double>(ixMax-1));
2533 el.
iB =
static_cast<int> (end *
static_cast<double>(ixMax-1));
2535 if (el.
iA < 0) el.
iA = 0;
2536 if (el.
iA > ixMax-1) el.
iA = ixMax-1;
2537 if (el.
iB < 0) el.
iB = 0;
2538 if (el.
iB > ixMax-1) el.
iB = ixMax-1;
2542 ExtendedString tmpName = el.
name;
2547 xLabel.
name = tmpName;
2548 xLabel.
iIndex = labelIndex; ++labelIndex;
2557 if (el.
side ==
"top")
2561 else if (el.
side ==
"bottom")
2566 for (i=el.
iA;i<el.
iB+1;++i)
2574 tmpName = xLabel.
name;
2580 else if (el.
side ==
"right" || el.
side ==
"left")
2607 el.
iA =
static_cast<int> (start *
static_cast<double>(iyMax-1));
2608 el.
iB =
static_cast<int> (end *
static_cast<double>(iyMax-1));
2610 if (el.
iA < 0) el.
iA = 0;
2611 if (el.
iA > iyMax-1) el.
iA = iyMax-1;
2612 if (el.
iB < 0) el.
iB = 0;
2613 if (el.
iB > iyMax-1) el.
iB = iyMax-1;
2617 ExtendedString tmpName = el.
name;
2622 xLabel.
name = tmpName;
2623 xLabel.
iIndex = labelIndex; ++labelIndex;
2632 if (el.
side ==
"right")
2636 else if (el.
side ==
"left")
2641 for (j=el.
iA;j<el.
iB+1;++j)
2649 tmpName = xLabel.
name;
2657 std::string msg(
"electrode side specification not recognized.\n");
2658 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
2667 xLabel.
name =
"NOFLUX";
2668 xLabel.
iIndex = labelIndex; ++labelIndex;
2672 int NOFLUXIndex = xLabel.
iIndex;
2676 for (j=0;j<
iyMax;++j)
2688 for (j=0;j<
iyMax;++j)
2700 for (i=0;i<
ixMax;++i)
2712 for (i=0;i<
ixMax;++i)
2725 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
2727 Xyce::dout() <<
"NOFLUX nodes:" << std::endl;
2728 for (
int nodeIndex=0;nodeIndex<xLabel.
mNodeVector.size();++nodeIndex)
2731 Xyce::dout() <<
"node="<<iNode<<
" x=" <<
xVector[iNode];
2732 Xyce::dout() <<
" y="<<
yVector[iNode] <<std::endl;
2736 tmpName = xLabel.
name;
2746 std::vector<int> edgeDone;
2749 for ( mapIter = mapStart; mapIter != mapEnd; ++mapIter )
2756 for (i=el.
iA+1;i<el.
iB+1;++i)
2767 else if (el.
side==
"bottom")
2770 for (i=el.
iA+1;i<el.
iB+1;++i)
2781 else if (el.
side==
"left")
2784 for (j=el.
iA+1;j<el.
iB+1;++j)
2795 else if (el.
side==
"right")
2798 for (j=el.
iA+1;j<el.
iB+1;++j)
2811 std::string msg(
"electrode side specification not recognized.\n");
2812 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
2818 for (j=1;j<
iyMax;++j)
2824 if (edgeDone[e1]!=1)
2832 for (j=1;j<
iyMax;++j)
2838 if (edgeDone[e1]!=1)
2846 for (i=1;i<
ixMax;++i)
2852 if (edgeDone[e1]!=1)
2860 for (i=1;i<
ixMax;++i)
2866 if (edgeDone[e1]!=1)
2873 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
2875 Xyce::dout() <<
"EDGEs:"<<std::endl;
2877 for (i=1;i<
ixMax;++i)
2883 Xyce::dout() <<
"edge: " << e1;
2885 Xyce::dout() <<
" y(A)="<<
yVector[mEdgeVector[e1].inodeA];
2886 Xyce::dout() <<
" x(B)="<<
xVector[mEdgeVector[e1].inodeB];
2887 Xyce::dout() <<
" y(B)="<<
yVector[mEdgeVector[e1].inodeB];
2888 Xyce::dout() <<
" label = " << mEdgeVector[e1].uLabel;
2889 Xyce::dout() << std::endl;
2891 Xyce::dout() << std::endl;
2894 for (i=1;i<
ixMax;++i)
2900 Xyce::dout() <<
"edge: " << e1;
2902 Xyce::dout() <<
" y(A)="<<
yVector[mEdgeVector[e1].inodeA];
2903 Xyce::dout() <<
" x(B)="<<
xVector[mEdgeVector[e1].inodeB];
2904 Xyce::dout() <<
" y(B)="<<
yVector[mEdgeVector[e1].inodeB];
2905 Xyce::dout() <<
" label = " << mEdgeVector[e1].uLabel;
2906 Xyce::dout() << std::endl;
2908 Xyce::dout() << std::endl;
2911 for (j=1;j<
iyMax;++j)
2917 Xyce::dout() <<
"edge: " << e1;
2919 Xyce::dout() <<
" y(A)="<<
yVector[mEdgeVector[e1].inodeA];
2920 Xyce::dout() <<
" x(B)="<<
xVector[mEdgeVector[e1].inodeB];
2921 Xyce::dout() <<
" y(B)="<<
yVector[mEdgeVector[e1].inodeB];
2922 Xyce::dout() <<
" label = " << mEdgeVector[e1].uLabel;
2923 Xyce::dout() << std::endl;
2925 Xyce::dout() << std::endl;
2928 for (j=1;j<
iyMax;++j)
2934 Xyce::dout() <<
"edge: " << e1;
2936 Xyce::dout() <<
" y(A)="<<
yVector[mEdgeVector[e1].inodeA];
2937 Xyce::dout() <<
" x(B)="<<
xVector[mEdgeVector[e1].inodeB];
2938 Xyce::dout() <<
" y(B)="<<
yVector[mEdgeVector[e1].inodeB];
2939 Xyce::dout() <<
" label = " << mEdgeVector[e1].uLabel;
2940 Xyce::dout() << std::endl;
2942 Xyce::dout() << std::endl;
2969 std::vector<mNode>::iterator first =
mNodeVector.begin ();
2970 std::vector<mNode>::iterator last =
mNodeVector.end ();
2971 std::vector<mNode>::iterator iter;
2976 for (iter=first;iter!=last;++iter)
2978 if (maxNodeNN < iter->cnode)
maxNodeNN = iter->cnode;
2990 std::map<std::string, mLabel>::iterator firstL =
mLabelMap.begin ();
2991 std::map<std::string, mLabel>::iterator lastL =
mLabelMap.end ();
2992 std::map<std::string, mLabel>::iterator iterL;
2994 for (iterL=firstL; iterL!=lastL; ++iterL)
2996 if (iterL->second.uType ==
TYPE_EDGE)
continue;
2998 std::vector<int>::iterator firstN = iterL->second.mNodeVector.begin ();
2999 std::vector<int>::iterator lastN = iterL->second.mNodeVector.end ();
3000 std::vector<int>::iterator iterN;
3002 iterL->second.vol = 0.0;
3004 for (iterN=firstN; iterN!=lastN; ++iterN)
3013 for (iter=first;iter!=last;++iter)
3015 if (xMax < iter->x)
xMax = iter->x;
3016 if (yMax < iter->y)
yMax = iter->y;
3017 if (
xMin > iter->x)
xMin = iter->x;
3018 if (
yMin > iter->y)
yMin = iter->y;
3037 FILE *file = fopen(dbFileName.c_str(),
"wt");
3039 fprintf(file,
"CELLS\n");
3040 fprintf(file,
" | | EDGES CELLS \n");
3041 fprintf(file,
" i | u | AB BC AC/CD AD AB BC AC/CD AD \n");
3042 fprintf(file,
"----- | --- | ----- ----- ----- ----- ----- ----- ----- -----\n");
3048 fprintf(file,
"%5u | ", i);
3049 if (c1.
uLabel != -1 ) fprintf(file,
"%3u | ", c1.
uLabel);
3050 else fprintf(file,
" | ");
3053 else fprintf(file,
" ");
3056 else fprintf(file,
" ");
3059 else fprintf(file,
" ");
3062 else fprintf(file,
" n/a ");
3066 else fprintf(file,
" ");
3069 else fprintf(file,
" ");
3072 else fprintf(file,
" ");
3075 else fprintf(file,
" n/a");
3077 fprintf(file,
"\n");
3079 fprintf(file,
"----- | --- | ----- ----- ----- ----- ----- ----- ----- -----\n");
3081 fprintf(file,
"\nEDGES\n");
3082 fprintf(file,
" | | NODES | | | | |\n");
3083 fprintf(file,
" i | u | A B | ilen | elen | Area1 | Area2 |\n");
3084 fprintf(file,
"----- | --- | ----- ----- | ------------ | ------------ | ------------ | ------------ |\n");
3089 fprintf(file,
"%5u | ", i);
3090 if (e1.
uLabel != -1 ) fprintf(file,
"%3u | ", e1.
uLabel);
3091 else fprintf(file,
" | ");
3092 fprintf(file,
"%5u %5u | %12.4e | %12.4e | %12.4e | %12.4e |\n",
3096 fprintf(file,
"\nNODES\n");
3097 fprintf(file,
" | | |\n");
3098 fprintf(file,
" i | x y | Area |\n");
3099 fprintf(file,
"----- | ------------ ------------ | ------------ |\n");
3104 fprintf(file,
"%5u | ", i);
3105 fprintf(file,
"%12.4e %12.4e | %12.4e |\n", n1.
x, n1.
y, n1.
area);
3108 fprintf(file,
"\nNodeEdgeInfo\n");
3111 fprintf(file,
"------\n");
3112 fprintf(file,
" node index = %d\n", i);
3115 fprintf(file,
" local edge index = %d\n", j);
3117 fprintf(file,
" global edge index = %d\n",
3120 fprintf(file,
" neighbor node = %d\n",
3123 fprintf(file,
" elen = %12.4e\n",
3126 fprintf(file,
" ilen = %12.4e\n",
3129 fprintf(file,
"------\n");
3149 std::map<std::string,mLabel>::iterator first =
mLabelMap.begin ();
3150 std::map<std::string,mLabel>::iterator last =
mLabelMap.end ();
3151 std::map<std::string,mLabel>::iterator iter =
mLabelMap.end ();
3153 Xyce::dout() << std::endl;
3154 Xyce::dout() <<
"Mesh Labels:" <<std::endl;
3155 Xyce::dout() <<
" Index # nodes Type Label";
3156 Xyce::dout() << std::endl;
3157 for (i=0, iter=first; iter!=last; ++iter, ++i)
3159 Xyce::dout().width(8);
3160 Xyce::dout() << iter->second.iIndex;
3161 Xyce::dout().width(10);
3162 Xyce::dout() << iter->second.cNode;
3164 if (iter->second.uType ==
TYPE_EDGE) Xyce::dout() <<
" Edge ";
3165 else Xyce::dout() <<
" Region ";
3167 Xyce::dout() <<
" ";
3168 Xyce::dout().width(15);
3169 Xyce::dout() << iter->second.name << std::endl;
3171 Xyce::dout() << std::endl;
3199 (
double &x,
double &y,
int inodeA,
int inodeB,
int inodeC)
3202 mNode nA = mNodeVector[inodeA];
3203 mNode nB = mNodeVector[inodeB];
3204 mNode nC = mNodeVector[inodeC];
3206 double x1 = nA.
x;
double y1 = nA.
y;
3207 double x2 = nB.
x;
double y2 = nB.
y;
3208 double x3 = nC.
x;
double y3 = nC.
y;
3210 double dx12 = x1 - x2;
3211 double dx23 = x2 - x3;
3212 double dx13 = x1 - x3;
3214 double m12 = (dx12) ? (y1 - y2) / dx12 : 0.0;
3215 double m23 = (dx23) ? (y2 - y3) / dx23 : 0.0;
3216 double m13 = (dx13) ? (y1 - y3) / dx13 : 0.0;
3217 double x12 = (x1 + x2) / 2.0;
double y12 = (y1 + y2) / 2.0;
3218 double x23 = (x2 + x3) / 2.0;
double y23 = (y2 + y3) / 2.0;
3219 double x13 = (x1 + x3) / 2.0;
double y13 = (y1 + y3) / 2.0;
3222 if (fabs(dx12) < fabs(dx23))
3224 iSmallest = (fabs(dx12) < fabs(dx13)) ?
TAG12 :
TAG13;
3228 iSmallest = (fabs(dx23) < fabs(dx13)) ?
TAG23 :
TAG13;
3234 x = (m13 * m23 * (y13 - y23) + m23 * x13 - m13 * x23) / (m23 - m13);
3238 x = (m13 * m12 * (y13 - y12) + m12 * x13 - m13 * x12) / (m12 - m13);
3242 x = (m12 * m23 * (y12 - y23) + m23 * x12 - m12 * x23) / (m23 - m12);
3247 if (fabs(m12) > fabs(m23))
3249 iLargest = (fabs(m12) > fabs(m13)) ?
TAG12 :
TAG13;
3253 iLargest = (fabs(m23) > fabs(m13)) ?
TAG23 :
TAG13;
3259 y = (x12 - x) / m12 + y12;
3263 y = (x23 - x) / m23 + y23;
3267 y = (x13 - x) / m13 + y13;
3271 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
3273 Xyce::dout() <<
"In computeIntPB:\n";
3274 Xyce::dout() <<
" inodeA = " << inodeA;
3275 Xyce::dout() <<
" inodeB = " << inodeB;
3276 Xyce::dout() <<
" inodeC = " << inodeC << std::endl;
3277 Xyce::dout() <<
" x1 = " << x1;
3278 Xyce::dout() <<
" y1 = " << y1 <<std::endl;
3280 Xyce::dout() <<
" x2 = " << x2;
3281 Xyce::dout() <<
" y2 = " << y2 <<std::endl;
3283 Xyce::dout() <<
" x3 = " << x3;
3284 Xyce::dout() <<
" y3 = " << y3 <<std::endl;
3286 Xyce::dout() <<
" iSmallest = " << iSmallest << std::endl;
3287 Xyce::dout() <<
" iLargest = " << iLargest << std::endl;
3289 Xyce::dout() <<
" m12 = " << m12 << std::endl;
3290 Xyce::dout() <<
" m23 = " << m23 << std::endl;
3291 Xyce::dout() <<
" m13 = " << m13 << std::endl;
3293 Xyce::dout() <<
" x = " << x << std::endl;
3294 Xyce::dout() <<
" y = " << y << std::endl;
3318 (
double x1,
double y1,
double x2,
double y2)
3320 double dx1 = x2 - x1;
3321 double dy1 = y2 - y1;
3322 double h = sqrt(dx1 * dx1 + dy1 * dy1);
3324 double A = pi * (x1 + x2) * h;
3344 (
double x1,
double y1,
double x2,
double y2,
double x3,
double y3)
3348 if (x1 > x2) { xT = x1; yT = y1; x1 = x2; y1 = y2; x2 = xT; y2 = yT; }
3349 if (x2 > x3) { xT = x2; yT = y2; x2 = x3; y2 = y3; x3 = xT; y3 = yT; }
3350 if (x1 > x2) { xT = x1; yT = y1; x1 = x2; y1 = y2; x2 = xT; y2 = yT; }
3353 double m13 = (y1 - y3) / (x1 - x3);
3356 double x2_2 = x2 * x2;
3357 double x2_3 = x2 * x2_2;
3361 if (fabs(x1-x2) > 1.0e-14)
3363 double m12 = (y1 - y2) / (x1 - x2);
3364 double x1_2 = x1 * x1;
3365 double x1_3 = x1 * x1_2;
3366 V12 = (m12 - m13) * ((x2_3 - x1_3) / 3.0 - x1 * (x2_2 - x1_2) / 2.0);
3371 if (fabs(x2-x3) > 1.0e-14)
3373 double m23 = (y2 - y3) / (x2 - x3);
3374 double x3_2 = x3 * x3;
3375 double x3_3 = x3 * x3_2;
3376 V23 = (m23 - m13) * ((x3_3 - x2_3) / 3.0 - x3 * (x3_2 - x2_2) / 2.0);
3381 double V = 2.0 * pi * (fabs(V12) + fabs(V23));
3400 double xl = n1.
x - n2.
x;
3401 double xr = n3.
x - n2.
x;
3402 double yl = n1.
y - n2.
y;
3403 double yr = n3.
y - n2.
y;
3405 double r = (xl*xr+yl*yr)/(sqrt(
sq(xl)+
sq(yl))*sqrt(
sq(xr)+
sq(yr)));
3406 if (r > 1.0) r = 1.0;
3407 else if (r < -1.0) r = -1.0;
3409 double angle = acos(r);
3427 std::vector<mCell>::iterator first =
mCellVector.begin();
3428 std::vector<mCell>::iterator last =
mCellVector.end ();
3429 std::vector<mCell>::iterator iter;
3432 for (i=0,iter=first; iter!=last ; ++i, ++iter)
3434 mCell & cellObj = *iter;
3436 int iedgeDA = cellObj.
iedgeDA;
3445 inode[0] = edgeAB.
inodeA;
3446 inode[1] = edgeAB.
inodeB;
3447 inode[2] = edgeBC.
inodeA;
3448 inode[3] = edgeBC.
inodeB;
3449 inode[4] = edgeCD.
inodeA;
3450 inode[5] = edgeCD.
inodeB;
3455 if (inode[0] == inode[2])
3460 cellObj.
inodeA = inode[1];
3461 cellObj.
inodeB = inode[0];
3462 cellObj.
inodeC = inode[3];
3464 else if (inode[0] == inode[3])
3469 cellObj.
inodeA = inode[1];
3470 cellObj.
inodeB = inode[0];
3471 cellObj.
inodeC = inode[2];
3473 else if (inode[1] == inode[2])
3478 cellObj.
inodeA = inode[0];
3479 cellObj.
inodeB = inode[1];
3480 cellObj.
inodeC = inode[3];
3487 cellObj.
inodeA = inode[0];
3488 cellObj.
inodeB = inode[1];
3489 cellObj.
inodeC = inode[2];
3499 inode[6] = edgeDA.
inodeA;
3500 inode[7] = edgeDA.
inodeB;
3502 if ((inode[0] == inode[2]) || (inode[0] == inode[3]))
3506 cellObj.
inodeA = inode[1];
3507 cellObj.
inodeB = inode[0];
3513 cellObj.
inodeA = inode[0];
3514 cellObj.
inodeB = inode[1];
3516 if ((inode[4] == inode[2]) || (inode[4] == inode[3]))
3520 cellObj.
inodeC = inode[4];
3521 cellObj.
inodeD = inode[5];
3527 cellObj.
inodeC = inode[5];
3528 cellObj.
inodeD = inode[4];
3551 double x1 = node1.
x;
3552 double y1 = node1.
y;
3553 double x2 = node2.
x;
3554 double y2 = node2.
y;
3555 double x3 = node3.
x;
3556 double y3 = node3.
y;
3558 double x12 = x2 - x1;
3559 double y12 = y2 - y1;
3560 double x13 = x3 - x1;
3561 double y13 = y3 - y1;
3563 double d12 = sqrt(x12*x12 + y12*y12);
3564 double d13 = sqrt(x13*x13 + y13*y13);
3566 double arg12 = x12/d12;
3567 double arg13 = x13/d13;
3569 if (arg12 < -1.0) arg12 = 1.0;
else if (arg12 > 1.0) arg12 = 1.0;
3570 if (arg13 < -1.0) arg13 = 1.0;
else if (arg13 > 1.0) arg13 = 1.0;
3572 double a12 = acos(arg12);
3573 double a13 = acos(arg13);
3577 if (y12 < 0) a12 = 2*pi - a12;
3578 if (y13 < 0) a13 = 2*pi - a13;
3580 return (a13 > a12) ?
true :
false;
3605 if (inode1 == inode3)
3611 else if (inode1 == inode4)
3617 else if (inode2 == inode3)
3637 if ((inode1 == inode3) || (inode1 == inode4))
3648 if ((inode5 == inode3) || (inode5 == inode4))
3673 (
int itri,
int *ainode,
int *aiedge,
int *aitri,
int *auLabel)
3675 elementNodes(itri,ainode);
3677 int iedgeAB, iedgeBC, iedgeCD, iedgeDA;
3679 iedgeAB = aiedge[0] = mCellVector[itri].iedgeAB;
3680 iedgeBC = aiedge[1] = mCellVector[itri].iedgeBC;
3681 iedgeCD = aiedge[2] = mCellVector[itri].iedgeCD;
3682 iedgeDA = aiedge[3] = mCellVector[itri].iedgeDA;
3684 aitri[0] = mCellVector[itri].icellAB;
3685 aitri[1] = mCellVector[itri].icellBC;
3686 aitri[2] = mCellVector[itri].icellCD;
3687 aitri[3] = mCellVector[itri].icellDA;
3689 auLabel[0] = mEdgeVector[iedgeAB].uLabel;
3690 auLabel[1] = mEdgeVector[iedgeBC].uLabel;
3691 auLabel[2] = mEdgeVector[iedgeCD].uLabel;
3692 auLabel[3] = (iedgeDA != -1) ? mEdgeVector[iedgeDA].uLabel : -1;
3705 (
NADJ &nadj,
int itri,
int iVertex,
int uIntLabel,
bool fCW)
3714 int aauVertices2Edge[4][4] =
3723 getElementInfo(itri, ainode, aiedge, aitri, auLabel);
3724 int cVertices = (ainode[
VERTEX_D] != -1) ? 4 : 3;
3727 nadj.
inode = ainode[iVertex];
3734 int nNextVertex = (fCCW == fCW) ? 1 : -1;
3735 int i = (iVertex + nNextVertex + cVertices) % cVertices;
3736 int i1 = aauVertices2Edge[iVertex][i];
3737 nadj.
ainode[0] = inode = ainode[i];
3738 nadj.
aiedge[0] = aiedge[i1];
3740 bool fBndry = (auLabel[i1] != uIntLabel);
3744 {
for(i = 0; i < cVertices; ++i)
3745 {
if (ainode[i] == nadj.
inode) iVertex = i;
3746 if (ainode[i] == inode) i1 = i;
3748 UINT iA = (iVertex + 1) % cVertices;
3749 UINT iB = (iVertex + cVertices - 1) % cVertices;
3750 UINT iV = (i1 == iA) ? iB : iA;
3751 UINT iE = aauVertices2Edge[iVertex][iV];
3753 nadj.
auLabel[cnode] = mCellVector[itri].uLabel;
3755 nadj.
ainode[cnode] = inode = ainode[iV];
3756 nadj.
aiedge[cnode] = aiedge[iE];
3757 nadj.
aielem[cnode] = aitri[iE];
3758 fBndry = fBndry || (auLabel[iE] != uIntLabel);
3766 if (itri == -1)
break;
3768 getElementInfo(itri, ainode, aiedge, aitri, auLabel);
3769 cVertices = (ainode[
VERTEX_D] != -1) ? 4 : 3;
3799 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
3801 Xyce::dout() <<
"In PDE_2DMesh::calcAdjacencyInfo" << std::endl;
3826 int *pinode = ainode;
3829 for(j = 0; j < 4; ++j, ++pinode)
3846 int c = nadjT.
cnode - 2;
3847 for(k = nadj.
cnode - 1; k != -1; --k)
3853 for(k = 0; k < c; ++k)
3879 for(k = 0; k < c-1; ++k)
3898 UINT cTriangle = (nadj.
fGotAll) ? c : c-1;
3901 nodeinfo.
Area = 0.0;
3902 for(k = 0; k < c; ++k)
3906 double elen = sqrt(
sq(xA-xB)+
sq(yA-yB));
3911 area =
areaAdjust(xA,yA,x[k],y[k],x[k+1],y[k+1]);
3915 ilen = sqrt(
sq(x[k]-x[k+1])+
sq(y[k]-y[k+1]));
3916 area = ilen * elen * 0.25;
3921 aedgeinfo[k].
ilen = ilen;
3922 aedgeinfo[k].
elen = elen;
3923 aedgeinfo[k].
Area1 = area;
3924 aedgeinfo[k].
Area2 = 0.0;
3925 nodeinfo.
Area += area;
3928 for(k = 0; k < cTriangle; ++k)
3936 double xAB = (xA+xB)/2.0;
3937 double yAB = (yA+yB)/2.0;
3938 double xAC = (xA+xC)/2.0;
3939 double yAC = (yA+yC)/2.0;
3949 (sqrt(
sq(xAB-xA)+
sq(yAB-yA))*sqrt(
sq(xAB-xo)+
sq(yAB-yo))+
3950 sqrt(
sq(xAC-xA)+
sq(yAC-yA))*sqrt(
sq(xAC-xo)+
sq(yAC-yo)));
3952 aedgeinfo[k].
Area2 = area;
3957 write(nFile, &nadj.
inode,
sizeof(INODE));
3959 write(nFile, aedgeinfo, c *
sizeof(
EDGEINFO));
3971 mNodeVector[*pinode].edgeInfoVector[k] = aedgeinfo[k];
4001 for(k = 0; k < cRegion; ++k, ++piBegin, ++piEnd)
4003 *piBegin = *piEnd = -1;
4009 for(k = 0; k < c; ++k, ++puLabel)
4011 int uLabel = *puLabel;
4015 aiEnd[uLabel] = k + 1;
4017 else if (
aiEnd[uLabel] == k) ++
aiEnd[uLabel];
4020 puLabel = nadj.
auLabel + c - 1;
4021 for(k = c; *puLabel == uLabel; --k, --puLabel);
4027 for(k = 0; k < cRegion; ++k, ++piBegin, ++piEnd)
4029 int iBegin = *piBegin;
4034 cEdge = (iEnd > iBegin) ? iEnd - iBegin : (c + iEnd) - iBegin;
4038 int cTEdge = (cEdge) ? cEdge - 1 : 0;
4041 nodeinfo.
Area = 0.0;
4042 for(l = 0; l < cEdge; ++l)
4044 int m = (iBegin + l) % nadj.
cnode;
4047 double xmdpt = (xA + xB) / 2.0;
4048 double ymdpt = (yA + yB) / 2.0;
4049 double elen = sqrt(
sq(xA-xB)+
sq(yA-yB));
4050 double ilen, area, x1, y1, x2, y2;
4052 { x1 = xmdpt; x2 = x[m+1];
4053 y1 = ymdpt; y2 = y[m+1];
4056 { x1 = x[m]; x2 = xmdpt;
4057 y1 = y[m]; y2 = ymdpt;
4060 { x1 = x[m]; x2 = x[m+1];
4061 y1 = y[m]; y2 = y[m+1];
4068 { ilen = sqrt(
sq(x1-x2)+
sq(y1-y2));
4069 area = ilen * elen / 4.0;
4074 aedgeinfo[l].
ilen = ilen;
4075 aedgeinfo[l].
elen = elen;
4076 aedgeinfo[l].
Area1 = area;
4077 aedgeinfo[l].
Area2 = 0.0;
4078 nodeinfo.
Area += area;
4081 for(l = 0; l < cTEdge; ++l)
4082 {
int m = (iBegin + l) % nadj.
cnode;
4083 int n = (m + 1) % nadj.
cnode;
4092 double xAB = (xA+xB)/2.0;
4093 double yAB = (yA+yB)/2.0;
4094 double xAC = (xA+xC)/2.0;
4095 double yAC = (yA+yC)/2.0;
4103 (sqrt(
sq(xAB-xA)+
sq(yAB-yA))*sqrt(
sq(xAB-xo)+
sq(yAB-yo))+
4104 sqrt(
sq(xAC-xA)+
sq(yAC-yA))*sqrt(
sq(xAC-xo)+
sq(yAC-yo)));
4106 aedgeinfo[l].
Area2 = area;
4110 int inode = numNodes + nadj.
inode * cRegion + k;
4112 write(nFile, &inode,
sizeof(INODE));
4114 write(nFile, aedgeinfo, cEdge *
sizeof(
EDGEINFO));
4127 mNodeVector[inode].edgeInfoVector[k] = aedgeinfo[k];
4144 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
4146 Xyce::dout() <<
"Done with PDE_2DMesh::calcAdjacencyInfo" << std::endl;
4162 bool bsuccess =
false;
4164 ExtendedString tmpName = labelName;
4183 ExtendedString tmpName = labelName;
4220 xvec_tmp.resize(
xVector.size(), 0.0);
4235 yvec_tmp.resize(
yVector.size(), 0.0);
4251 ExtendedString tmpName = labelName;
4288 double X0_1 = xScale;
4289 double X0_2 = xScale * X0_1;
4290 double X0_3 = xScale * X0_2;
4292 double scaleILEN, scaleArea;
4293 double scaleELEN = X0_1;
4295 if (
cylGeom) { scaleILEN = X0_2; scaleArea = X0_3; }
4296 else { scaleILEN = X0_1; scaleArea = X0_2; }
4298 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
4300 Xyce::dout() << section_divider << std::endl;
4301 Xyce::dout() <<
" In PDE_2DMesh::scaleMesh"<<std::endl;
4302 Xyce::dout() <<
" scaleELEN = " << scaleELEN <<std::endl;
4303 Xyce::dout() <<
" scaleILEN = " << scaleILEN <<std::endl;
4304 Xyce::dout() <<
" scaleArea = " << scaleArea <<std::endl;
4305 Xyce::dout() << section_divider << std::endl;
4309 scaleELEN = 1.0/scaleELEN;
4310 scaleILEN = 1.0/scaleILEN;
4311 scaleArea = 1.0/scaleArea;
4318 std::vector<EDGEINFO>::iterator firstEI =
mNodeVector[i].edgeInfoVector.begin ();
4319 std::vector<EDGEINFO>::iterator lastEI =
mNodeVector[i].edgeInfoVector.end ();
4320 std::vector<EDGEINFO>::iterator iterEI;
4321 for (iterEI=firstEI;iterEI!=lastEI;++iterEI)
4323 iterEI->ilen *= scaleILEN;
4324 iterEI->elen *= scaleELEN;
4325 iterEI->Area1 *= scaleArea;
4326 iterEI->Area2 *= scaleArea;
4344 std::map<std::string, mLabel>::iterator firstL =
mLabelMap.begin ();
4345 std::map<std::string, mLabel>::iterator lastL =
mLabelMap.end ();
4346 std::map<std::string, mLabel>::iterator iterL;
4348 for (iterL=firstL; iterL!=lastL; ++iterL)
4350 iterL->second.vol *= scaleArea;
4351 iterL->second.surfArea *= scaleILEN;
4380 int iNodeA,iNodeB,iNodeC,iNodeD;
4393 if (istatus == 2)
return F[inode];
4394 if (istatus == -1)
return 0.0;
4409 intAHelp.
f0 = F[iNodeA];
4410 intAHelp.
f1 = F[iNodeB];
4411 intAHelp.
f2 = F[iNodeC];
4419 intAHelp.
f0 = F[iNodeA];
4420 intAHelp.
f2 = F[iNodeC];
4426 double f1 = F[iNodeB];
4427 double f2 = F[iNodeD];
4429 if( pow((r1-r),2.0)+pow((z1-z),2.0) <
4430 pow((r2-r),2.0)+pow((z2-z),2.0)
4474 int iEdgeAB, iEdgeBC, iEdgeCD, iEdgeDA;
4476 double ABx, ABy, ABangle, ABFx, ABFy;
4477 double BCx, BCy, BCangle, BCFx, BCFy;
4478 double CDx, CDy, CDangle, CDFx, CDFy;
4479 double DAx, DAy, DAangle, DAFx, DAFy;
4480 double xA, xB, yA, yB;
4516 if (triFlag) iEdgeDA = -1;
4525 ABangle =
compAngle(xB,yB, xA,yA, (xA+0.1), yA);
4529 ABFx = F[iEdgeAB] * cos(ABangle);
4530 ABFy = F[iEdgeAB] * sin(ABangle);
4537 BCangle =
compAngle(xB,yB, xA,yA, (xA+0.1), yA);
4541 BCFx = F[iEdgeBC] * cos(BCangle);
4542 BCFy = F[iEdgeBC] * sin(BCangle);
4549 CDangle =
compAngle(xB,yB, xA,yA, (xA+0.1), yA);
4553 CDFx = F[iEdgeCD] * cos(CDangle);
4554 CDFy = F[iEdgeCD] * sin(CDangle);
4563 DAangle =
compAngle(xB,yB, xA,yA, (xA+0.1), yA);
4567 DAFx = F[iEdgeDA] * cos(DAangle);
4568 DAFy = F[iEdgeDA] * sin(DAangle);
4579 bool madeIt =
false;
4616 alpha = ((ABy < CDy)?1.0:0.0) * (z-ABy)/(CDy-ABy) +
4617 ((ABy >= CDy)?1.0:0.0) * (ABy-z)/(ABy-CDy);
4618 xvec = (1.0-alpha)*ABFx + alpha*CDFx;
4620 alpha = ((BCx < DAx)?1.0:0.0) * (r-BCx)/(DAx-BCx) +
4621 ((BCx >= DAx)?1.0:0.0) * (BCx-r)/(BCx-DAx);
4622 yvec = (1.0-alpha)*BCFy + alpha*DAFy;
4628 alpha = ((BCy < DAy)?1.0:0.0) * (z-BCy)/(DAy-BCy) +
4629 ((BCy >= DAy)?1.0:0.0) * (BCy-z)/(BCy-DAy);
4630 xvec = (1.0-alpha)*BCFx + alpha*DAFx;
4632 alpha = ((ABx < CDx)?1.0:0.0) * (r-ABx)/(CDx-ABx) +
4633 ((ABx >= CDx)?1.0:0.0) * (ABx-r)/(ABx-CDx);
4634 yvec = (1.0-alpha)*ABFy + alpha*CDFy;
4647 double rtest = ((2.1e-3)/209.0) * 22.0;
4648 double rtol = fabs(rtest/1000.0);
4649 double ztest = -9.0e-5;
4650 double ztol = fabs(ztest/1000.0);
4653 (xvec != 0.0 && !(xvec > 0.0) && !(xvec < 0.0)) ||
4654 (yvec != 0.0 && !(yvec > 0.0) && !(yvec < 0.0))
4655 || (r >= (rtest-rtol) && r <= (rtest+rtol) &&
4656 z >= (ztest-ztol) && z <= (ztest+ztol))
4659 Xyce::dout() << Xyce::section_divider << std::endl;
4660 Xyce::dout() <<
"Vector Interpolation failed!" << std::endl;
4661 Xyce::dout() << std::endl;
4662 Xyce::dout() <<
" iCell = " << iCell << std::endl;
4663 Xyce::dout() <<
" alpha = " << alpha << std::endl;
4664 Xyce::dout() <<
" number of cells on mesh: " <<
numCells << std::endl;
4665 Xyce::dout() <<
" r = " << r << std::endl;
4666 Xyce::dout() <<
" z = " << z << std::endl;
4667 Xyce::dout() << std::endl;
4668 Xyce::dout() <<
" xvec = " << xvec << std::endl;
4669 Xyce::dout() <<
" yvec = " << yvec << std::endl;
4671 Xyce::dout() <<
" inodeA = " << iA << std::endl;
4672 Xyce::dout() <<
" inodeB = " << iB << std::endl;
4673 Xyce::dout() <<
" inodeC = " << iC << std::endl;
4674 Xyce::dout() <<
" inodeD = " << iD << std::endl;
4683 Xyce::dout() <<
" ABangle = " << ABangle <<
" = " <<(ABangle/pi)<<
" * PI" << std::endl;
4684 Xyce::dout() <<
" BCangle = " << BCangle <<
" = " <<(BCangle/pi)<<
" * PI" << std::endl;
4685 Xyce::dout() <<
" CDangle = " << CDangle <<
" = " <<(CDangle/pi)<<
" * PI" << std::endl;
4687 Xyce::dout() <<
" DAangle = " << DAangle <<
" = " <<(DAangle/pi)<<
" * PI" << std::endl;
4689 Xyce::dout() <<
" ABFx = " << ABFx << std::endl;
4690 Xyce::dout() <<
" ABFy = " << ABFy << std::endl;
4691 Xyce::dout() <<
" BCFx = " << BCFx << std::endl;
4692 Xyce::dout() <<
" BCFy = " << BCFy << std::endl;
4693 Xyce::dout() <<
" CDFx = " << CDFx << std::endl;
4694 Xyce::dout() <<
" CDFy = " << CDFy << std::endl;
4695 Xyce::dout() <<
" DAFx = " << DAFx << std::endl;
4696 Xyce::dout() <<
" DAFy = " << DAFy << std::endl;
4698 Xyce::dout() <<
" F[iEdgeAB] = " << F[iEdgeAB] <<std::endl;
4699 Xyce::dout() <<
" F[iEdgeBC] = " << F[iEdgeBC] <<std::endl;
4700 Xyce::dout() <<
" F[iEdgeCD] = " << F[iEdgeCD] <<std::endl;
4702 Xyce::dout() <<
" F[iEdgeDA] = " << F[iEdgeDA] <<std::endl;
4703 Xyce::dout() << Xyce::section_divider << std::endl;
4704 Report::DevelFatal() <<
"Vector Interpolation failed";
4757 int iEdgeAB,iEdgeBC,iEdgeCD,iEdgeDA;
4758 int iNodeA,iNodeB,iNodeC,iNodeD;
4759 bool doneFlag =
false;
4763 int ixhi,ixlo,iyhi,iylo;
4786 if(r==
xVector[iNodeA] && z==
yVector[iNodeA]){inode=iNodeA; istatus=2;}
4787 if(r==
xVector[iNodeB] && z==
yVector[iNodeB]){inode=iNodeB; istatus=2;}
4788 if(r==
xVector[iNodeC] && z==
yVector[iNodeC]){inode=iNodeC; istatus=2;}
4790 if(r==
xVector[iNodeD] && z==
yVector[iNodeD]){inode=iNodeD; istatus=2;}
4792 if (istatus == 2)
return;
4800 intEHelp.
xB =
xVector[mEdgeVector[iEdgeAB].inodeB];
4801 intEHelp.
yA =
yVector[mEdgeVector[iEdgeAB].inodeA];
4802 intEHelp.
yB =
yVector[mEdgeVector[iEdgeAB].inodeB];
4810 intEHelp.
xA =
xVector[mEdgeVector[iEdgeBC].inodeA];
4811 intEHelp.
xB =
xVector[mEdgeVector[iEdgeBC].inodeB];
4812 intEHelp.
yA =
yVector[mEdgeVector[iEdgeBC].inodeA];
4813 intEHelp.
yB =
yVector[mEdgeVector[iEdgeBC].inodeB];
4821 intEHelp.
xA =
xVector[mEdgeVector[iEdgeCD].inodeA];
4822 intEHelp.
xB =
xVector[mEdgeVector[iEdgeCD].inodeB];
4823 intEHelp.
yA =
yVector[mEdgeVector[iEdgeCD].inodeA];
4824 intEHelp.
yB =
yVector[mEdgeVector[iEdgeCD].inodeB];
4834 intEHelp.
xA =
xVector[mEdgeVector[iEdgeDA].inodeA];
4835 intEHelp.
xB =
xVector[mEdgeVector[iEdgeDA].inodeB];
4836 intEHelp.
yA =
yVector[mEdgeVector[iEdgeDA].inodeA];
4837 intEHelp.
yB =
yVector[mEdgeVector[iEdgeDA].inodeB];
4847 if((ixhi >= 1) && (ixlo >= 1) && (iyhi >= 1) && (iylo >= 1))
4861 double minimum = +1.0e+99;
4875 if (ABmin <= minimum) { minimum = ABmin; iC = AB_iC; }
4887 if (BCmin <= minimum) { minimum = BCmin; iC = BC_iC; }
4899 if (CDmin <= minimum) { minimum = CDmin; iC = CD_iC; }
4911 if (DAmin < minimum) { minimum = DAmin; iC = DA_iC; }
4925 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
4927 Xyce::dout() << std::endl;
4928 Xyce::dout() <<
"iCell = " << iCell << std::endl;
4929 Xyce::dout() <<
"r = " << r <<
" z = " << z << std::endl;
4930 Xyce::dout() <<
"curr_min = " << curr_min << std::endl;
4931 Xyce::dout() << std::endl;
4935 Xyce::dout() <<
"AB_iC = " << AB_iC;
4936 Xyce::dout() <<
" ABmin = " << ABmin;
4942 Xyce::dout() <<
"BC_iC = " << BC_iC;
4943 Xyce::dout() <<
" BCmin = " << BCmin;
4949 Xyce::dout() <<
"CD_iC = " << CD_iC;
4950 Xyce::dout() <<
" CDmin = " << CDmin;
4956 Xyce::dout() <<
"DA_iC = " << DA_iC;
4957 Xyce::dout() <<
" DAmin = " << DAmin;
4984 double minDist = +1.0e99;
4986 double rdist,zdist,dist;
4993 rdist = r-x1; zdist = z-y1;
4994 dist = sqrt (rdist*rdist + zdist*zdist);
4995 if (dist < minDist) { minDist = dist; }
5003 rdist = r-x1; zdist = z-y1;
5004 dist = sqrt (rdist*rdist + zdist*zdist);
5005 if (dist < minDist) { minDist = dist; }
5013 rdist = r-x1; zdist = z-y1;
5014 dist = sqrt (rdist*rdist + zdist*zdist);
5015 if (dist < minDist) { minDist = dist; }
5023 rdist = r-x1; zdist = z-y1;
5024 dist = sqrt (rdist*rdist + zdist*zdist);
5025 if (dist < minDist) { minDist = dist; }
5043 double x1,
double y1,
5044 double x2,
double y2,
5045 double x3,
double y3)
5052 xl = x1 - x2; yl = y1 - y2;
5053 xr = x3 - x2; yr = y3 - y2;
5055 r = (xl*xr+yl*yr)/(sqrt(
sq(xl)+
sq(yl))*sqrt(
sq(xr)+
sq(yr)));
5056 if (r > 1.0) r = 1.0;
5057 else if (r < -1.0) r = -1.0;
5059 if (xl*yr-xr*yl > 0) angle = 2*
M_PI-angle;
5088 aiNodeVector.reserve (32);
5089 aiEdgeVector.reserve (32);
5090 aiCellVector.reserve (32);
5091 auLabelVector.reserve (32);
5094 for (
int i=0;i<32;++i)
5096 aiNodeVector[i] = -1;
5097 aiEdgeVector[i] = -1;
5098 aiCellVector[i] = -1;
5099 auLabelVector[i] = -1;
5140 iedgeAB (-1), iedgeBC (-1), iedgeCD (-1), iedgeDA (-1),
5141 icellAB (-1), icellBC (-1), icellCD (-1), icellDA (-1)
5208 double f =
aa*r +
bb*z +
cc;
5225 if( (y1-
y0)*(x2-x1)- (y2-y1)*(x1-
x0) != 0.0)
5228 ((y1-
y0)*(x2-
x1) - (y2-y1)*(x1-
x0));
5303 if( (yA <= z && yB >= z) || (yB <= z && yA >= z) )
5329 if((xA <= r && xB >= r)||(xB <= r && xA >= r))
5334 if((yA <= z && yB >= z)||(yB <= z && yA >= z))
double * getDopingVector()
double computeAngle(int inode1, int inode2, int inode3)
bool initializeInternalMesh(int nx, int ny, double xlength, double ylength, int numElectrodes, std::string &outputMeshFileName, std::map< std::string, PDE_2DElectrode * > &elMap, bool cylFlag)
bool computeIntPB(double &x, double &y, int inodeA, int inodeB, int inodeC)
Pure virtual class to augment a linear system.
const DeviceOptions * devOptions_
std::vector< double > yVector
bool setupEdge(double r, double z)
bool writeSGFMeshFile(const std::string &meshFileName_tmp)
std::vector< mLabel > mLabelVector
std::vector< mEdge > mEdgeVector
std::vector< int > mNodeVector
bool setupDefaultLabels(int numberElectrodes)
bool labelEdgeType(std::string &labelName)
bool interpVector(double *F, double r, double z, double &xvec, double &yvec)
bool setupInternalAdjacencyInfo()
void getElementInfo(int itri, int *ainode, int *aiedge, int *aitri, int *auLabel)
bool fCCWorder(int inode1, int inode2, int inode3)
void elementNodes(int itri, int *ainode)
std::map< std::string, mLabel > mLabelMap
bool scaleMesh(double xScale)
std::vector< int > visitCellFlagVec
std::vector< double > dopingVector
std::vector< int > afVisitedVec
double compAngle(double x1, double y1, double x2, double y2, double x3, double y3)
#define EDGESTATUS_INTERIOR
double interpReg(double r, double z)
bool given(const std::string ¶meter_name) const
given returns true if the value was specified in the netlist (not defaulted).
void initNodeAdjStructure(NADJ &nadj, int itri, int iVertex, int uIntLabel, bool fCW)
std::vector< mCell > mCellVector
double findMinDist(int iCell, double r, double z)
double interp(double *F, double r, double z)
bool errorCheckElectrodes(int numElectrodes, std::map< std::string, PDE_2DElectrode * > &elMap)
double areaAdjust(double x1, double y1, double x2, double y2, double x3, double y3)
std::vector< mNode > mNodeVector
bool setupInternalLabels(int numberElectrodes, std::map< std::string, PDE_2DElectrode * > &elMap)
PDE_2DMesh & operator=(PDE_2DMesh const &rhsMesh)
void findCell(double r, double z, int &isuccess, int &inode, int &iCell, int iStartCell=0)
bool setupInternalMesh(int nx, int ny, double xlength, double ylength)
bool initializeMesh(const std::string &meshFileName_tmp)
std::vector< int > mNodeVector
std::vector< double > xVector
bool resizeMesh(double xlength, double ylength)
double lengthAdjust(double x1, double y1, double x2, double y2)
#define EDGESTATUS_EXTERIOR
bool readSGFMeshFile(const std::string &meshFileName_tmp)
bool labelNameExist(std::string &labelName)