void recombine( gamete_pointer base_gamete, gamete_pointer other_gamete, typename gamete_type::bitset_type * res, unsigned int nRec, typename recombination_method_type::result_type & result_status ) { ++m_nRecomb; m_nRecombEvents += nRec; typename gamete_type::alphabet_t::pointer alpha = base_gamete->getAlphabet(); recombination_points rec_points; generateRecombination( rec_points, nRec ); recombination_method_type recomb( base_gamete->getBits(), res, alpha, &rec_points, &result_status ); boost::to_block_range( *other_gamete->getBits(), recomb ); }
void ONE_commonTerms(ONEdevice *pDevice, BOOLEAN currentOnly, BOOLEAN tranAnalysis, ONEtranInfo *info) { ONEelem *pElem; ONEedge *pEdge; ONEnode *pNode; int index, eIndex; double psi1, psi2, psi, nConc=0.0, pConc=0.0, nC, pC, nP1, pP1; double dPsiN, dPsiP; double bPsiN, dbPsiN, bMPsiN, dbMPsiN; double bPsiP, dbPsiP, bMPsiP, dbMPsiP; double mun, dMun, mup, dMup; double conc1, conc2; double cnAug, cpAug; /* evaluate all node (including recombination) and edge quantities */ for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) { pElem = pDevice->elemArray[eIndex]; cnAug = pElem->matlInfo->cAug[ELEC]; cpAug = pElem->matlInfo->cAug[HOLE]; for (index = 0; index <= 1; index++) { if (pElem->evalNodes[index]) { pNode = pElem->pNodes[index]; if (pNode->nodeType != CONTACT) { psi = pDevice->dcSolution[pNode->psiEqn]; if (pElem->elemType == SEMICON) { nConc = pDevice->dcSolution[pNode->nEqn]; pConc = pDevice->dcSolution[pNode->pEqn]; if (Srh) { recomb(nConc, pConc, pNode->tn, pNode->tp, cnAug, cpAug, pNode->nie, &pNode->uNet, &pNode->dUdN, &pNode->dUdP); } else { pNode->uNet = 0.0; pNode->dUdN = 0.0; pNode->dUdP = 0.0; } if (pNode->baseType == P_TYPE && pConc <= 0.0) { pConc = pNode->na; } else if (pNode->baseType == N_TYPE && nConc <= 0.0) { nConc = pNode->nd; } } } else { /* a contact node */ psi = pNode->psi; if (pElem->elemType == SEMICON) { nConc = pNode->nConc; pConc = pNode->pConc; } } /* store info in the state tables */ *(pDevice->devState0 + pNode->nodePsi) = psi; if (pElem->elemType == SEMICON) { *(pDevice->devState0 + pNode->nodeN) = nConc; *(pDevice->devState0 + pNode->nodeP) = pConc; if (tranAnalysis && pNode->nodeType != CONTACT) { pNode->dNdT = integrate(pDevice->devStates, info, pNode->nodeN); pNode->dPdT = integrate(pDevice->devStates, info, pNode->nodeP); } } } } pEdge = pElem->pEdge; pNode = pElem->pLeftNode; if (pNode->nodeType != CONTACT) { psi1 = pDevice->dcSolution[pNode->psiEqn]; } else { psi1 = pNode->psi; } pNode = pElem->pRightNode; if (pNode->nodeType != CONTACT) { psi2 = pDevice->dcSolution[pNode->psiEqn]; } else { psi2 = pNode->psi; } pEdge->dPsi = psi2 - psi1; *(pDevice->devState0 + pEdge->edgeDpsi) = pEdge->dPsi; } /* calculate the current densities and mobility values */ for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) { pElem = pDevice->elemArray[eIndex]; pEdge = pElem->pEdge; if (pElem->elemType == SEMICON) { dPsiN = pEdge->dPsi + pEdge->dCBand; dPsiP = pEdge->dPsi - pEdge->dVBand; bernoulli(dPsiN, &bPsiN, &dbPsiN, &bMPsiN, &dbMPsiN, !currentOnly); bernoulli(dPsiP, &bPsiP, &dbPsiP, &bMPsiP, &dbMPsiP, !currentOnly); nC = *(pDevice->devState0 + pElem->pLeftNode->nodeN); nP1 = *(pDevice->devState0 + pElem->pRightNode->nodeN); pC = *(pDevice->devState0 + pElem->pLeftNode->nodeP); pP1 = *(pDevice->devState0 + pElem->pRightNode->nodeP); conc1 = pElem->pLeftNode->totalConc; conc2 = pElem->pRightNode->totalConc; pEdge->jn = (bPsiN * nP1 - bMPsiN * nC); pEdge->jp = (bPsiP * pC - bMPsiP * pP1); mun = pEdge->mun; dMun = 0.0; mup = pEdge->mup; dMup = 0.0; MOBfieldDep(pElem->matlInfo, ELEC, dPsiN * pElem->rDx, &mun, &dMun); MOBfieldDep(pElem->matlInfo, HOLE, dPsiP * pElem->rDx, &mup, &dMup); mun *= pElem->rDx; dMun *= pElem->rDx * pElem->rDx; mup *= pElem->rDx; dMup *= pElem->rDx * pElem->rDx; /* * The base continuity equation makes use of mu/dx in eg. The base * length has already been calculated and converted to normalized, * reciprocal form during setup. The name should be changed, but that's * a big hassle. */ for (index = 0; index <= 1; index++) { if (pElem->evalNodes[index]) { pNode = pElem->pNodes[index]; if (pNode->baseType == N_TYPE) { pNode->eg = pEdge->mun * pDevice->baseLength; } else if (pNode->baseType == P_TYPE) { pNode->eg = pEdge->mup * pDevice->baseLength; } } } pEdge->jn *= mun; pEdge->jp *= mup; if (!currentOnly) { if (dMun == 0.0) { pEdge->dJnDpsiP1 = mun * (dbPsiN * nP1 - dbMPsiN * nC); } else { pEdge->dJnDpsiP1 = dMun * (bPsiN * nP1 - bMPsiN * nC) + mun * (dbPsiN * nP1 - dbMPsiN * nC); } pEdge->dJnDn = -mun * bMPsiN; pEdge->dJnDnP1 = mun * bPsiN; if (dMup == 0.0) { pEdge->dJpDpsiP1 = mup * (dbPsiP * pC - dbMPsiP * pP1); } else { pEdge->dJpDpsiP1 = dMup * (bPsiP * pC - bMPsiP * pP1) + mup * (dbPsiP * pC - dbMPsiP * pP1); } pEdge->dJpDp = mup * bPsiP; pEdge->dJpDpP1 = -mup * bMPsiP; } } if (tranAnalysis) { pEdge->jd = -integrate(pDevice->devStates, info, pEdge->edgeDpsi) * pElem->rDx; } } }
gamete_pointer method1( gamete_pointer base_gamete, gamete_pointer other_gamete, unsigned int gen ) { #ifdef LOGGING static unsigned int nCalls = 0; std::ostringstream oss; oss << gen << "." << nCalls++; std::string log_key = oss.str(); #endif unsigned int nMut = m_rng->nextPoisson( m_mu ); unsigned int nRec = 0; gamete_pointer res = NULL; if( base_gamete != other_gamete ) { nRec = m_rng->nextPoisson( m_rho ); if( m_rng->nextBool() ) { res = base_gamete; base_gamete = other_gamete; other_gamete = res; res = NULL; } } else if( nMut == 0 ) { // both gametes are the same // AND no new mutations will be added // hence just return a copy #ifdef LOGGING global_log.put( log_key + ".result", "Same gamete; Copying base gamete"); #endif return base_gamete->copy(); // } else { // // both gametes are the same // // recombination will result in no new gametes // // therefore skip recombinations. // // there will be mutations, so clone one of the gametes // assert( nMut > 0 ); // assert( nRec == 0 ); } #ifdef LOGGING global_log.put( log_key + ".nRec", nRec ); global_log.put( log_key + ".nMut", nMut ); #endif if( nRec > 0 ) { ++m_nRecomb; m_nRecombEvents += nRec; typename gamete_type::bitset_type symm_diff; typename alphabet_type::pointer alpha = base_gamete->getAlphabet(); recombination_points rec_points; generateRecombination( rec_points, nRec ); #ifdef LOGGING state_log_type p; for( unsigned int i = 0; i < rec_points.size(); ++i ) { state_log_type t; t.put( "", rec_points[i]); p.push_back( std::make_pair( "", t ) ); } global_log.add_child( log_key + ".points", p ); #endif #ifdef LOGGING typename recombination_method_type::result_type stats(gen); #else typename recombination_method_type::result_type stats; #endif recombination_method_type recomb( base_gamete->getBits(), &symm_diff, alpha, &rec_points, &stats ); boost::to_block_range( *other_gamete->getBits(), recomb ); if( nMut == 0) { if( stats.is_empty ) { #ifdef LOGGING global_log.put( log_key + ".result" , "EMPTY"); #endif return gamete_type::EMPTY.copy(); } else if( stats.match_base ) { #ifdef LOGGING global_log.put( log_key + ".result" , "Matched Base"); #endif return base_gamete->copy(); } else if( stats.match_alt ) { #ifdef LOGGING global_log.put( log_key + ".result" , "Matched Alternate"); #endif return other_gamete->copy(); } else { #ifdef LOGGING global_log.put( log_key + ".result" , "New gamete, no new mutations"); #endif res = new gamete_type( symm_diff, alpha ); return res; } } else { #ifdef LOGGING global_log.put( log_key + ".result", "New gamete, New mutations"); #endif res = new gamete_type( symm_diff, alpha ); } } else if( nMut == 0 ) { #ifdef LOGGING global_log.put( log_key + ".result", "Different Gametes; No Mutaions; Copy random gamete" ); #endif return base_gamete->copy(); } else { #ifdef LOGGING global_log.put( log_key + ".result", "Different Gamete; Clone random gamete"); #endif res = base_gamete->clone(); } assert( res != NULL); assert( nMut > 0 ); ++m_nMut; m_nMutEvents += nMut; #ifdef LOGGING state_log_type m; #endif while( nMut-- ) { typedef symbol_generator< typename alphabet_type::locus_t, typename alphabet_type::allele_t, typename alphabet_type::index_type, alphabet_type > sgen_type; typedef typename sgen_type::symbol_type symbol_type; static sgen_type sgen; symbol_type s = sgen( res->getAlphabet(), (infinite_site * ) NULL ); //std::cout << "Adding variant: " << s << std::endl; #ifdef LOGGING state_log_type _m; _m.put( "", s ); m.push_back( std::make_pair("", _m)); #endif res->addVariant( s ); } #ifdef LOGGING global_log.add_child( log_key + ".mutations", m); #endif return res; }