コード例 #1
0
ファイル: SolverImpl.hpp プロジェクト: runesorland/pcmsolver
/*! \brief Builds the CPCM matrix
 *  \param[in] cav the discretized cavity
 *  \param[in] gf_i Green's function inside the cavity
 *  \param[in] epsilon permittivity outside the cavity
 *  \param[in] correction CPCM correction factor
 *  \return the \f$ \mathbf{K} = f(\varepsilon)\mathbf{S}^{-1} \f$ matrix
 *
 *  This function calculates the PCM matrix.
 *  The matrix is not symmetrized and is not symmetry packed.
 */
inline Eigen::MatrixXd CPCMMatrix(const Cavity & cav, const IGreensFunction & gf_i, double epsilon, double correction)
{
  // The total size of the cavity
  size_t cavitySize = cav.size();
  // The number of irreps in the group
  int nrBlocks = cav.pointGroup().nrIrrep();
  // The size of the irreducible portion of the cavity
  int dimBlock = cav.irreducible_size();

  // Compute SI and DI on the whole cavity, regardless of symmetry
  TIMER_ON("Computing SI");
  Eigen::MatrixXd SI = gf_i.singleLayer(cav.elements());
  TIMER_OFF("Computing SI");

  // Perform symmetry blocking
  // If the group is C1 avoid symmetry blocking, we will just pack the fullPCMMatrix
  // into "block diagonal" when all other manipulations are done.
  if (cav.pointGroup().nrGenerators() != 0) {
    TIMER_ON("Symmetry blocking");
    symmetryBlocking(SI, cavitySize, dimBlock, nrBlocks);
    TIMER_OFF("Symmetry blocking");
  }

  double fact = (epsilon - 1.0)/(epsilon + correction);
  // Invert SI  using LU decomposition with full pivoting
  // This is a rank-revealing LU decomposition, this allows us
  // to test if SI is invertible before attempting to invert it.
  Eigen::FullPivLU<Eigen::MatrixXd> SI_LU(SI);
  if (!(SI_LU.isInvertible()))
    PCMSOLVER_ERROR("SI matrix is not invertible!", BOOST_CURRENT_FUNCTION);
  return fact * SI_LU.inverse();
}
コード例 #2
0
ファイル: SolverImpl.hpp プロジェクト: runesorland/pcmsolver
/*! \brief Builds the **anisotropic** IEFPCM matrix
 *  \param[in] cav the discretized cavity
 *  \param[in] gf_i Green's function inside the cavity
 *  \param[in] gf_o Green's function outside the cavity
 *  \return the \f$ \mathbf{K} = \mathbf{T}^{-1}\mathbf{R}\mathbf{A} \f$ matrix
 *
 *  This function calculates the PCM matrix. We use the following definitions:
 *  \f[
 *     \begin{align}
 *       \mathbf{T} &=
 *      \left(2\pi\mathbf{I} - \mathbf{D}_\mathrm{e}\mathbf{A}\right)\mathbf{S}_\mathrm{i}
 *      +\mathbf{S}_\mathrm{e}\left(2\pi\mathbf{I} +
 *      \mathbf{A}\mathbf{D}_\mathrm{i}^\dagger\right) \\
 *      \mathbf{R} &=
 *      \left(2\pi\mathbf{A}^{-1} - \mathbf{D}_\mathrm{e}\right) -
 *      \mathbf{S}_\mathrm{e}\mathbf{S}^{-1}_\mathrm{i}\left(2\pi\mathbf{A}^{-1}-\mathbf{D}_\mathrm{i}\right)
 *     \end{align}
 *  \f]
 *  The matrix is not symmetrized and is not symmetry packed.
 */
inline Eigen::MatrixXd anisotropicIEFMatrix(const Cavity & cav, const IGreensFunction & gf_i, const IGreensFunction & gf_o)
{
  // The total size of the cavity
  size_t cavitySize = cav.size();
  // The number of irreps in the group
  int nrBlocks = cav.pointGroup().nrIrrep();
  // The size of the irreducible portion of the cavity
  int dimBlock = cav.irreducible_size();

  // Compute SI, DI and SE, DE on the whole cavity, regardless of symmetry
  TIMER_ON("Computing SI");
  Eigen::MatrixXd SI = gf_i.singleLayer(cav.elements());
  TIMER_OFF("Computing SI");
  TIMER_ON("Computing DI");
  Eigen::MatrixXd DI = gf_i.doubleLayer(cav.elements());
  TIMER_OFF("Computing DI");
  TIMER_ON("Computing SE");
  Eigen::MatrixXd SE = gf_o.singleLayer(cav.elements());
  TIMER_OFF("Computing SE");
  TIMER_ON("Computing DE");
  Eigen::MatrixXd DE = gf_o.doubleLayer(cav.elements());
  TIMER_OFF("Computing DE");

  // Perform symmetry blocking
  // If the group is C1 avoid symmetry blocking, we will just pack the fullPCMMatrix
  // into "block diagonal" when all other manipulations are done.
  if (cav.pointGroup().nrGenerators() != 0) {
    TIMER_ON("Symmetry blocking");
    symmetryBlocking(DI, cavitySize, dimBlock, nrBlocks);
    symmetryBlocking(SI, cavitySize, dimBlock, nrBlocks);
    symmetryBlocking(DE, cavitySize, dimBlock, nrBlocks);
    symmetryBlocking(SE, cavitySize, dimBlock, nrBlocks);
    TIMER_OFF("Symmetry blocking");
  }

  Eigen::MatrixXd a = cav.elementArea().asDiagonal();
  Eigen::MatrixXd Id = Eigen::MatrixXd::Identity(cavitySize, cavitySize);

  // 1. Form T
  TIMER_ON("Assemble T matrix");
  Eigen::MatrixXd fullPCMMatrix = ((2 * M_PI * Id - DE * a) * SI + SE * (2 * M_PI * Id + a * DI.adjoint().eval()));
  TIMER_OFF("Assemble T matrix");
  // 2. Invert T using LU decomposition with full pivoting
  //    This is a rank-revealing LU decomposition, this allows us
  //    to test if T is invertible before attempting to invert it.
  TIMER_ON("Invert T matrix");
  Eigen::FullPivLU<Eigen::MatrixXd> T_LU(fullPCMMatrix);
  if (!(T_LU.isInvertible())) PCMSOLVER_ERROR("T matrix is not invertible!", BOOST_CURRENT_FUNCTION);
  fullPCMMatrix = T_LU.inverse();
  TIMER_OFF("Invert T matrix");
  Eigen::FullPivLU<Eigen::MatrixXd> SI_LU(SI);
  if (!(SI_LU.isInvertible())) PCMSOLVER_ERROR("SI matrix is not invertible!", BOOST_CURRENT_FUNCTION);
  TIMER_ON("Assemble T^-1R matrix");
  fullPCMMatrix *= ((2 * M_PI * Id - DE * a) - SE * SI_LU.inverse() * (2 * M_PI * Id - DI * a));
  TIMER_OFF("Assemble T^-1R matrix");

  return fullPCMMatrix;
}
コード例 #3
0
ファイル: Timers.c プロジェクト: yguo89/RTOS
/******** Timer_SetPeriod **************************************************
// Set the interrupt period for Timer										
// Input: 
//		timer	-	one of the Timer_T value ( Timer1A, Timer1B... )
//		period	-	n of the 20ns time slices
// Output: none											
// ------------------------------------------------------------------------*/
void Timer_SetPeriod ( Timer_T timer, unsigned long period ) 
{
	if ( TIMER_ON(timer/2) )
	{
		// only can set period for timer that has been initialized
		TimerLoadSet ( Timer_Base[timer], get_half_timer(timer), period);
	}
}
コード例 #4
0
ファイル: Timers.c プロジェクト: yguo89/RTOS
/******** Timer_GetTime ****************************************************
// Get the current value in timer										
// Input: timer is one of the Timer_T value ( Timer1A, Timer1B... )
// Output: n of the 20ns time slices. 
//		   Return 0xFFFFFFFF if the timer is not initialized 										
// ------------------------------------------------------------------------*/
unsigned long Timer_GetTime ( Timer_T timer ) 
{
	if ( TIMER_ON(timer/2) )
	{
		return TimerValueGet( Timer_Base[timer], get_half_timer(timer) );
	}
	else
	{
		return 0xFFFFFFFF;
	}
}
コード例 #5
0
ファイル: SolverImpl.hpp プロジェクト: runesorland/pcmsolver
/*! \brief Builds the **isotropic** IEFPCM matrix
 *  \param[in] cav the discretized cavity
 *  \param[in] gf_i Green's function inside the cavity
 *  \param[in] epsilon permittivity outside the cavity
 *  \return the \f$ \mathbf{K} = \mathbf{T}^{-1}\mathbf{R}\mathbf{A} \f$ matrix
 *
 *  This function calculates the PCM matrix. We use the following definitions:
 *  \f[
 *     \begin{align}
 *       \mathbf{T} &=
 *      \left(2\pi\frac{\varepsilon+1}{\varepsilon-1}\mathbf{I} - \mathbf{D}_\mathrm{i}\mathbf{A}\right)\mathbf{S}_\mathrm{i} \\
 *      \mathbf{R} &=
 *      \left(2\pi\mathbf{A}^{-1} - \mathbf{D}_\mathrm{i}\right)
 *     \end{align}
 *  \f]
 *  The matrix is not symmetrized and is not symmetry packed.
 */
inline Eigen::MatrixXd isotropicIEFMatrix(const Cavity & cav, const IGreensFunction & gf_i, double epsilon)
{
  // The total size of the cavity
  size_t cavitySize = cav.size();
  // The number of irreps in the group
  int nrBlocks = cav.pointGroup().nrIrrep();
  // The size of the irreducible portion of the cavity
  int dimBlock = cav.irreducible_size();

  // Compute SI and DI on the whole cavity, regardless of symmetry
  TIMER_ON("Computing SI");
  Eigen::MatrixXd SI = gf_i.singleLayer(cav.elements());
  TIMER_OFF("Computing SI");
  TIMER_ON("Computing DI");
  Eigen::MatrixXd DI = gf_i.doubleLayer(cav.elements());
  TIMER_OFF("Computing DI");

  // Perform symmetry blocking
  // If the group is C1 avoid symmetry blocking, we will just pack the fullPCMMatrix
  // into "block diagonal" when all other manipulations are done.
  if (cav.pointGroup().nrGenerators() != 0) {
    TIMER_ON("Symmetry blocking");
    symmetryBlocking(DI, cavitySize, dimBlock, nrBlocks);
    symmetryBlocking(SI, cavitySize, dimBlock, nrBlocks);
    TIMER_OFF("Symmetry blocking");
  }

  Eigen::MatrixXd a = cav.elementArea().asDiagonal();
  Eigen::MatrixXd Id = Eigen::MatrixXd::Identity(cavitySize, cavitySize);

  // Tq = -Rv -> q = -(T^-1 * R)v = -Kv
  // T = (2 * M_PI * fact * aInv - DI) * a * SI; R = (2 * M_PI * aInv - DI)
  // fullPCMMatrix_ = K = T^-1 * R * a
  // 1. Form T
  double fact = (epsilon + 1.0)/(epsilon - 1.0);
  TIMER_ON("Assemble T matrix");
  Eigen::MatrixXd fullPCMMatrix = (2 * M_PI * fact * Id - DI * a) * SI;
  TIMER_OFF("Assemble T matrix");
  // 2. Invert T using LU decomposition with full pivoting
  //    This is a rank-revealing LU decomposition, this allows us
  //    to test if T is invertible before attempting to invert it.
  TIMER_ON("Invert T matrix");
  Eigen::FullPivLU<Eigen::MatrixXd> T_LU(fullPCMMatrix);
  if (!(T_LU.isInvertible()))
    PCMSOLVER_ERROR("T matrix is not invertible!", BOOST_CURRENT_FUNCTION);
  fullPCMMatrix = T_LU.inverse();
  TIMER_OFF("Invert T matrix");
  // 3. Multiply T^-1 and R
  TIMER_ON("Assemble T^-1R matrix");
  fullPCMMatrix *= (2 * M_PI * Id - DI * a);
  TIMER_OFF("Assemble T^-1R matrix");

  return fullPCMMatrix;
}
コード例 #6
0
ファイル: CPCMSolver.cpp プロジェクト: PCMSolver/pcmsolver
void CPCMSolver::buildSystemMatrix_impl(const ICavity & cavity,
                                        const IGreensFunction & gf_i,
                                        const IGreensFunction & gf_o,
                                        const IBoundaryIntegralOperator & op) {
  if (!isotropic_)
    PCMSOLVER_ERROR("C-PCM is defined only for isotropic environments!");
  TIMER_ON("Computing S");
  double epsilon = gf_o.permittivity();
  S_ = op.computeS(cavity, gf_i);
  S_ /= (epsilon - 1.0) / (epsilon + correction_);
  // Get in Hermitian form
  if (hermitivitize_)
    utils::hermitivitize(S_);
  TIMER_OFF("Computing S");

  // Symmetry-pack
  // The number of irreps in the group
  int nrBlocks = cavity.pointGroup().nrIrrep();
  // The size of the irreducible portion of the cavity
  int dimBlock = cavity.irreducible_size();
  utils::symmetryPacking(blockS_, S_, dimBlock, nrBlocks);

  built_ = true;
}
コード例 #7
0
ファイル: Timers.c プロジェクト: yguo89/RTOS
/******** Timer_Init *******************************************************
// Initialize timer as either CCP, PWM or regular timer
// Input: 
//		timer		-	one of the Timer_T value ( Timer1A, Timer1B... )
//		config		-	indicates the operational mode of the timer
//		xParameter	-	additional configure value, depends the mode of timer
//		tBool		-	if true then enable timer right away	
// Output: none
// ------------------------------------------------------------------------*/
void Timer_Init ( Timer_T timer, Timer_Config config, unsigned long xParameter, tBoolean enable )
{
	unsigned long timer_base, timer_config;

	// only turn on system control for the same timer once
	if ( !(TIMER_ON(timer/2)) )
	{
		SysCtlPeripheralEnable ( Timer_Periph[timer] );	
		TIMER_POWER_ON ( timer/2 );
	}

	// disable timer before configure
	TimerDisable ( Timer_Base[timer], get_half_timer(timer) );

	// determine what user want this timer to do
	switch ( config )
	{
		case Timer_CCP:
		{
			if ( timer >= NUM_CCP )
			{
				// return if the timer does not associate with a CCP pin
				return;
			}

			// initialize CCP pin
			GPIO_Init ( CCP_Port[timer], CCP_Pin[timer], 0, 0, CCP );

			// initialize Timer
			if ( timer % 2 )
			{
				// timer B, 16bit capture
				TimerConfigure ( Timer_Base[timer], TIMER_CFG_16_BIT_PAIR | TIMER_CFG_B_ONE_SHOT | TIMER_CFG_B_CAP_TIME );	
				TimerControlEvent ( Timer_Base[timer], TIMER_B, xParameter);  
				Timer_IntFlag[timer] = TIMER_CAPB_EVENT;
			}
			else
			{
				// timer A, 16bit capture
				TimerConfigure ( Timer_Base[timer], TIMER_CFG_16_BIT_PAIR | TIMER_CFG_A_ONE_SHOT | TIMER_CFG_A_CAP_TIME ); 
				TimerControlEvent ( Timer_Base[timer], TIMER_A, xParameter);  
				Timer_IntFlag[timer] = TIMER_CAPA_EVENT;
			}

			break;
		}

		case Timer_PWM:
		{
			break;
		}

		case Timer_Periodic:
		{
			break;
		}

		case Timer_OneTime:
		{
			break;
		}

		default:
		{
			break;
		}
	}

	if ( enable )
	{
		TimerEnable ( Timer_Base[timer], get_half_timer(timer) );
	}
}