예제 #1
0
void SkyMap::mouseReleaseEvent( QMouseEvent * ) {
    if ( ZoomRect.isValid() ) {
        stopTracking();
        SkyPoint newcenter = projector()->fromScreen( ZoomRect.center(), data->lst(), data->geo()->lat() );
        setFocus( &newcenter );
        setDestination( newcenter );

        //Zoom in on center of Zoom Circle, by a factor equal to the ratio
        //of the sky pixmap's width to the Zoom Circle's diameter
        float factor = float(width()) / float(ZoomRect.width());
        setZoomFactor( Options::zoomFactor() * factor );
    }
    setDefaultMouseCursor();
    ZoomRect = QRect(); //invalidate ZoomRect

    if(m_previewLegend) {
        slotCancelLegendPreviewMode();
    }

    //false if double-clicked, because it's unset there.
    if (mouseButtonDown) {
        mouseButtonDown = false;
        if ( slewing ) {
            slewing = false;
            if ( Options::useAltAz() )
                setDestinationAltAz( focus()->alt(), focus()->az() );
            else
                setDestination( *focus() );
        }
        forceUpdate();	// is needed because after moving the sky not all stars are shown
    }
    // if middle button was pressed unset here
    midMouseButtonDown = false;
}
예제 #2
0
void SkyMap::mouseDoubleClickEvent( QMouseEvent *e ) {
    if ( e->button() == Qt::LeftButton && !projector()->unusablePoint( e->pos() ) ) {
        mouseButtonDown = false;
        if( e->x() != width()/2 || e->y() != height()/2 )
            slotCenter();
    }
}
예제 #3
0
double SpringEstimator::update1Arm(double timeStep, int nrIter)
{
  for(int iter = 0; iter < nrIter; ++iter)
  {
    updateArmsData();

    // compute task 3 error and jacobian
    // minimize distance between the arm 0 end effector and the target
    const sva::PTransformd& arm0 =
        arms_[0].mbc.bodyPosW[arms_[0].endEffectorIndex];
    tasks_[0].err.noalias() = sva::rotationError(target_, arm0.rotation(), 1e-7);
    tasks_[0].jac.block(0, 0, 3, arms_[0].jac.dof()).noalias() =
        arms_[0].jacMat.block(0, 0, 3, arms_[0].jac.dof());

    for(std::size_t i = 0; i < jTargetData_.size(); ++i)
    {
      const JointTargetData& jtd = jTargetData_[i];
      tasks_[1].err(i) = q_(jtd.jointIndexInQ) - jtd.target;
    }

    // solve all the tasks
    // minimize the distance and minimum joint velocity
    solveT1(tasks_[0], lstsqMinTol_, lstsqRelTol_);
    for(std::size_t i = 1; i < tasks_.size(); ++i)
    {
      projector(tasks_[i - 1], projs_[i - 1], projs_[i], projMinTol_,
                projRelTol_);
      solveTN(tasks_[i - 1], projs_[i], tasks_[i], lstsqMinTol_, lstsqRelTol_);
    }

    qd_.noalias() = tasks_.back().qd;
    q_.noalias() -= qd_*timeStep;
  }
  return 0.;
}
예제 #4
0
  void playWithHomeTheater() {

    // Create all the parts of the home theatre system
    Amplifier amp("Top-O-Line Amplifier");
    CdPlayer cd("Top-O-Line CD Player", &amp);
    DvdPlayer dvd("Top-O-Line DVD Player", &amp);
    Screen screen("My Theater Screen");
    PopcornPopper popper("My Popcorn Popper");
    Tuner tuner("Top-O-Line AM/FM Tuner", &amp);
    TheaterLights lights("Theater Ceiling Lights");
    Projector projector("Top-O-Line Projector");

    popper.on();  // Turn on the popcorn popper...
    popper.pop(); // and start popping...

    lights.dim(10); // Dim the lights to 10%... 
    
    screen.down();  // Put the screen down...

    projector.on();             // Turn on the projector...
    projector.setInput(&dvd);    // set it to DVD...
    projector.wideScreenMode(); // and put it on wide screen mode for the movie...

    amp.on();                // Turn on the amp...
    amp.setInput(&dvd);       // set it to DVD and...
    amp.setSurroundSound();  // put it into surround sound mode...
    amp.setVolume(11);       // and set the volume to 11...

    dvd.on();                            // Turn on the DVD player...
    dvd.play("Raiders of the lost ark"); // and FINALLY, play the movie!

    // What about shutting everything down again?!
    // How would you play a CD? etc...
  }
예제 #5
0
/*----------------------------------------------------------------------*
 |  project master nodes onto slave element (private)        mwgee 10/05|
 *----------------------------------------------------------------------*/
bool MOERTEL::Overlap::build_mxi()
{
  // project the master segment's nodes onto the slave segment
  MOERTEL::Node** mnode  = mseg_.Nodes();
  MOERTEL::Projector projector(inter_.IsOneDimensional(),OutLevel());
  double gap;
  for (int i=0; i<mseg_.Nnode(); ++i)
  {
    // project node i onto sseg

    projector.ProjectNodetoSegment_SegmentNormal(*mnode[i],sseg_,mxi_[i],gap);

/*
	mxi_[i] output. mxi_[i][0] is the \xi coordinate of the projection in sseg_, and
	mxi_[i][1] is the \eta coordinate of the projection in sseg_.
*/

#if 0
    // check whether i is inside sseg
    if (mxi_[i][0]<=1. && mxi_[i][1]<=abs(1.-mxi_[i][0]) && mxi_[i][0]>=0. && mxi_[i][1]>=0.)
    {
	  std::cout << "OVERLAP: master node in: " << mnode[i]->Id() << endl;
    }
#endif    

  }
  havemxi_ = true;
  return true;
}
예제 #6
0
 std::vector<carve::geom::vector<2> > Face<ndim>::projectedVertices() const {
   p2_adapt_project<ndim> proj = projector();
   std::vector<carve::geom::vector<2> > result;
   result.reserve(nVertices());
   for (size_t i = 0; i < nVertices(); ++i) {
     result.push_back(proj(vertex(i)->v));
   }
   return result;
 }
    void OrthogonalizedBumpFinder::GetVegaBumps(std::vector<std::vector<Matrix> >& theBumps) const
    {
        OrthogonalProjections projector(derivativesProducer_.getAllOnePercentBumps(),
                                                            multiplierCutOff_,
                                                             tolerance_  );


        Size numberRestrictedBumps(projector.numberValidVectors());

        boost::shared_ptr<MarketModel> marketmodel(derivativesProducer_.getInputBumps().associatedModel());
        const EvolutionDescription& evolution(marketmodel->evolution());

        Size numberSteps = evolution.numberOfSteps();
        Size numberRates = evolution.numberOfRates();
        Size factors = marketmodel->numberOfFactors();

        theBumps.resize(numberSteps);
       // recall that the bumps: We do the outermost vector by time step and inner one by which vega.

        for (Size i=0; i < theBumps.size(); ++i)
            theBumps[i].resize(numberRestrictedBumps);

        Matrix modelMatrix(numberRates, factors,0.0);

        for (Size i=0;  i< numberSteps; ++i)
            for (Size j=0; j < numberRestrictedBumps; ++j)
                theBumps[i][j] = modelMatrix;

        const std::vector<VegaBumpCluster>& bumpClusters(derivativesProducer_.getInputBumps().allBumps());


        Size bumpIndex =0;

        for (Size instrument=0; instrument < projector.validVectors().size(); ++instrument)
        {
            if (projector.validVectors()[instrument])
            {
                for (Size cluster =0; cluster< bumpClusters.size(); ++cluster)
                {
                    Real magnitude = projector.GetVector(instrument)[cluster];

                    for (Size step = bumpClusters[cluster].stepBegin(); step <  bumpClusters[cluster].stepEnd(); ++step)
                        for (Size rate = bumpClusters[cluster].rateBegin(); rate < bumpClusters[cluster].rateEnd(); ++rate)
                            for (Size factor = bumpClusters[cluster].factorBegin(); factor <  bumpClusters[cluster].factorEnd(); ++factor)
                                theBumps[step][bumpIndex][rate][factor] = magnitude;
                }

                ++bumpIndex;


            }

        }



    }
예제 #8
0
void ABC_forcing(struct Field fldi,
			 double dt) {

  const double A=NTOTAL*(2*M_PI)*(2*M_PI)*nu, B=NTOTAL*(2*M_PI)*(2*M_PI)*nu, C=NTOTAL*(2*M_PI)*(2*M_PI)*nu;

  const double kf=1.0;
  int i, j, k;
  int divisor,quociente,resto;

	
// ABC forcing

// Na direcao z nao precisa setar valores negativos de k, pois espelhamento e' feito automaticamente       
	if ((rank==0)){
	i=0;
        j=0;
        k=1;
	fldi.vx[IDX3D] += -0.5*A*I * dt;
	fldi.vy[IDX3D] += 0.5*A * dt;
	i=0;
	j=1;
        k=0;
	fldi.vx[IDX3D] += 0.5*C * dt;
	fldi.vz[IDX3D] += -0.5*C*I * dt;
	j=NY_COMPLEX - 1;
	fldi.vx[IDX3D] += 0.5*C * dt;
	fldi.vz[IDX3D] += 0.5*C*I * dt;
	}

	divisor=NX_COMPLEX/NPROC;
	quociente=(int)1/divisor;
	resto=fmod(1,divisor);

	// Somente kx eh paralelizado:
	if (rank==quociente){
	i=resto;
	j=0;
	k=0;
	fldi.vy[IDX3D] += -0.5*B*I * dt;
	fldi.vz[IDX3D] += 0.5*B * dt;
	}
	if (rank==(NPROC-1-quociente)){
	i = NX_COMPLEX/NPROC-resto;
	j=0;
	k=0;
	fldi.vy[IDX3D] += 0.5*B*I * dt;
	fldi.vz[IDX3D] += 0.5*B * dt;
	}
	
	projector(fldi.vx,fldi.vy,fldi.vz);
	
	return;
}
예제 #9
0
int main(int argc,char* argv[])
	{
	/* Open the requested 3D video stream: */
	std::string colorFileName=argv[1];
	colorFileName.append(".color");
	std::string depthFileName=argv[1];
	depthFileName.append(".depth");
	Kinect::FileFrameSource frameSource(colorFileName.c_str(),depthFileName.c_str());
	
	/* Get the 3D video stream's intrinsic parameters: */
	Kinect::FrameSource::IntrinsicParameters ip=frameSource.getIntrinsicParameters();
	
	/* Create a 3D video projector: */
	Kinect::Projector projector(frameSource);
	projector.setFilterDepthFrames(false,true);
	
	/* Read pairs of frames from the source and export them to a sequence of Lightwave Object files: */
	unsigned int minIndex=argc>3?atoi(argv[3]):0;
	unsigned int maxIndex=argc>4?atoi(argv[4]):Math::Constants<unsigned int>::max;
	unsigned int frameIndex=0;
	std::cout<<"Processing frame      0"<<std::flush;
	while(true)
		{
		std::cout<<"\b\b\b\b\b\b"<<std::setw(6)<<frameIndex<<std::flush;
		/* Read the next pair of frames: */
		Kinect::FrameBuffer color=frameSource.readNextColorFrame();
		Kinect::FrameBuffer depth=frameSource.readNextDepthFrame();
		
		/* Bail out if either frame is invalid: */
		if(color.timeStamp==Math::Constants<double>::max||depth.timeStamp==Math::Constants<double>::max)
			break;
		
		if(frameIndex>=minIndex&&frameIndex<maxIndex)
			{
			/* Convert the depth frame to a mesh: */
			Kinect::MeshBuffer mesh;
			projector.processDepthFrame(depth,mesh);
			
			/* Export the frame pair to an LWO file: */
			char lwoFileName[1024];
			snprintf(lwoFileName,sizeof(lwoFileName),argv[2],frameIndex);
			writeFrames(ip,color,mesh,lwoFileName);
			}
		
		++frameIndex;
		}
	std::cout<<std::endl;
	
	return 0;
	}
예제 #10
0
  void playWithHomeTheaterFacade() {
    // Create all the parts of the home theatre system
    // Not encapsulated or owned by the facade.
    Amplifier amp("Top-O-Line Amplifier");
    CdPlayer cd("Top-O-Line CD Player", &amp);
    DvdPlayer dvd("Top-O-Line DVD Player", &amp);
    Screen screen("My Theater Screen");
    PopcornPopper popper("My Popcorn Popper");
    Tuner tuner("Top-O-Line AM/FM Tuner", &amp);
    TheaterLights lights("Theater Ceiling Lights");
    Projector projector("Top-O-Line Projector");

    HomeTheaterFacade theater(&amp, &tuner, &dvd, &cd, &projector, &lights, &screen, &popper);
    theater.watchMovie("Raiders of the Lost Ark");
    theater.endMovie();
  }
예제 #11
0
/*----------------------------------------------------------------------*
 |  project slave nodes onto master element (private)        mwgee 11/05|
 *----------------------------------------------------------------------*/
bool MOERTEL::Overlap::build_sxim()
{
  // project the slave segment's nodes onto the master segment
  int nsnode = sseg_.Nnode();
  MOERTEL::Node** snode  = sseg_.Nodes();
  MOERTEL::Projector projector(inter_.IsOneDimensional(),OutLevel());
  double gap;
  for (int i=0; i<nsnode; ++i)
  {
    // project node i onto sseg
    projector.ProjectNodetoSegment_NodalNormal(*snode[i],mseg_,sxim_[i],gap);
#if 0
    // check whether i is inside sseg
    if (sxim_[i][0]<=1. && sxim_[i][1]<=abs(1.-sxim_[i][0]) && sxim_[i][0]>=0. && sxim_[i][1]>=0.)
    {
	  std::cout << "OVERLAP: slave node in: " << snode[i]->Id() << endl;
    }
#endif    
  }
  havesxim_ = true;
  return true;
}
예제 #12
0
		void RoadChunkTableSync::ProjectAddress(
			const Point& point,
			double maxDistance,
			Address& address,
			EdgeProjector<boost::shared_ptr<MainRoadChunk> >::CompatibleUserClassesRequired requiredUserClasses
		){
			EdgeProjector<boost::shared_ptr<MainRoadChunk> >::From paths(
				SearchByMaxDistance(
					point,
					maxDistance,
					Env::GetOfficialEnv(),
					UP_LINKS_LOAD_LEVEL
			)	);

			if(!paths.empty())
			{
				EdgeProjector<boost::shared_ptr<MainRoadChunk> > projector(paths, maxDistance, requiredUserClasses);

				try
				{
					EdgeProjector<boost::shared_ptr<MainRoadChunk> >::PathNearby projection(
						projector.projectEdge(
							*point.getCoordinate()
					)	);

					address.setGeometry(
						boost::shared_ptr<Point>(
							CoordinatesSystem::GetStorageCoordinatesSystem().getGeometryFactory().createPoint(
								projection.get<0>()
					)	)	);
					address.setRoadChunk(projection.get<1>().get());
					address.setMetricOffset(projection.get<2>());
				}
				catch(EdgeProjector<boost::shared_ptr<MainRoadChunk> >::NotFoundException)
				{
				}
			}
		}
    InterfaceT)::ProjectNodes_SlavetoMaster_Orthogonal()
{
  if (!IsComplete()) {
    std::stringstream oss;
    oss << "***ERR*** "
           "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n"
        << "***ERR*** Complete() not called on interface " << Id() << "\n"
        << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
    throw MoertelT::ReportError(oss);
  }
  if (lcomm_ == Teuchos::null) return true;

  int mside = MortarSide();
  int sside = OtherSide(mside);

  // iterate over all nodes of the slave side and project those belonging to me
  std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator
      scurr;
  for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) {
    Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second;

#if 0
    std::cout << "now projecting\n " << *snode;
#endif

    if (NodePID(snode->Id()) != lcomm_->getRank()) continue;

    const double*                                         sx = snode->XCoords();
    double                                                mindist = 1.0e+20;
    Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> closenode =
        Teuchos::null;

    // find a node on the master side, that is closest to me
    std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::
        iterator mcurr;
    for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) {
      Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode =
          mcurr->second;
      const double* mx = mnode->XCoords();

      // build distance | mnode->XCoords() - snode->XCoords() |
      double dist = 0.0;
      for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]);
      dist = sqrt(dist);
      if (dist <= mindist) {
        mindist   = dist;
        closenode = mnode;
      }
      // std::cout << "snode " << snode->Id() << " mnode " << mnode->Id() << "
      // mindist " << mindist  << " dist " << dist << std::endl;
    }
    if (closenode == Teuchos::null) {
      std::stringstream oss;
      oss << "***ERR*** "
             "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n"
          << "***ERR*** Weired: for slave node " << snode->Id()
          << " no closest master node found\n"
          << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      throw MoertelT::ReportError(oss);
    }

    // get segments attached to closest node cnode
    int nmseg                                          = closenode->Nseg();
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** msegs = closenode->Segments();

    // create a projection-iterator
    MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT)
        projector(IsOneDimensional(), OutLevel());

    // loop segments and find all projections onto them
    int nsseg                                          = snode->Nseg();
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** ssegs = snode->Segments();
    for (int i = 0; i < nmseg; ++i) {
      // loop all segments that are adjacent to the slave node
      for (int j = 0; j < nsseg; ++j) {
        // project the slave node onto that master segment
        double xi[2];
        xi[0] = xi[1] = 0.0;
        double gap;
        projector.ProjectNodetoSegment_Orthogonal_to_Slave(
            *snode, *(msegs[i]), xi, gap, *(ssegs[j]));

        // check whether this projection is good
        bool ok = false;
        if (IsOneDimensional()) {
          if (abs(xi[0]) < 1.01) ok = true;
        } else {
          std::stringstream oss;
          oss << "***ERR*** "
                 "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n"
              << "***ERR*** not impl. for 3D\n"
              << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
          throw MoertelT::ReportError(oss);
        }

        if (ok)  // the projection is good
        {
          // create a projected node and store it in snode
          MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
              new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
                  *snode, xi, msegs[i], ssegs[j]->Id());
          snode->SetProjectedNode(pnode);
          snode->SetGap(gap);
#if 0
          std::cout << " snode id: " << pnode->Id()
               << " projects on mseg: " << msegs[i]->Id()
               << " orth to sseg " << ssegs[j]->Id() << std::endl;
#endif
        }
      }  // for (int j=0; j<nsseg; ++j)
    }    // for (int i=0; i<nmseg; ++i)
  }  // for (scurr=rnode_[sside].begin(); scurr!=rnode_[sside].end(); ++scurr)

  // loop all slave nodes again and make projections redundant
  if (lcomm_->getSize() > 1) {
    std::vector<double> bcast(10 * rnode_[sside].size());
    for (int proc = 0; proc < lcomm_->getSize(); ++proc) {
      int blength = 0;
      if (proc == lcomm_->getRank()) {
        for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end();
             ++scurr) {
          Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode =
              scurr->second;
          if (proc != NodePID(snode->Id()))
            continue;  // cannot have a projection on a node i don't own
          int npnode = 0;
          Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)>*
              pnode = snode->GetProjectedNode(npnode);
          if (!pnode) continue;  // no projection on this one
          bcast[blength] = (double)snode->Id();
          ++blength;
          bcast[blength] = (double)npnode;
          ++blength;
          for (int j = 0; j < npnode; ++j) {
            bcast[blength] = (double)pnode[j]->Segment()->Id();
            ++blength;
            const double* xi = pnode[j]->Xi();
            bcast[blength]   = xi[0];
            ++blength;
            bcast[blength] = xi[1];
            ++blength;
            bcast[blength] = pnode[j]->OrthoSegment();
            ++blength;
            bcast[blength] = pnode[j]->Gap();
            ++blength;
          }
          if ((int)bcast.size() < blength + 20) bcast.resize(bcast.size() + 40);
        }  // for (mcurr=rnode_[mside].begin(); mcurr!=rnode_[mside].end();
           // ++mcurr)
        if (blength >= (int)bcast.size()) {
          std::stringstream oss;
          oss << "***ERR*** "
                 "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n"
              << "***ERR*** Overflow in communication buffer occured\n"
              << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
          throw MoertelT::ReportError(oss);
        }
      }  // if (proc==lComm()->MyPID())

      Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength);
      if (proc != lcomm_->getRank()) bcast.resize(blength);
      Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]);

      if (proc != lcomm_->getRank()) {
        int i;
        for (i = 0; i < blength;) {
          int nid = (int)bcast[i];
          ++i;
          Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode =
              GetNodeView(nid);
          int npnode = (int)bcast[i];
          ++i;
          for (int j = 0; j < npnode; ++j) {
            int sid = (int)bcast[i];
            ++i;
            double* xi = &bcast[i];
            ++i;
            ++i;
            int orthseg = (int)bcast[i];
            ++i;
            double gap = bcast[i];
            ++i;
            Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg =
                GetSegmentView(sid);
            MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
                new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
                    *snode, xi, seg.get(), orthseg);
            snode->SetProjectedNode(pnode);
            snode->SetGap(gap);
          }
        }
        if (i != blength) {
          std::stringstream oss;
          oss << "***ERR*** "
                 "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n"
              << "***ERR*** Mismatch in dimension of recv buffer: " << i
              << " != " << blength << "\n"
              << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
          throw MoertelT::ReportError(oss);
        }
      }  // if (proc!=lComm()->MyPID())
    }    // for (int proc=0; proc<lComm()->NumProc(); ++proc)
    bcast.clear();
  }  // if (lComm()->NumProc()>1)

#if 1
  // Postprocess the projections
  // The slave side of the interface might be larger then the master side
  // of the interface so not all slave nodes have a projection.
  // For those slave nodes without a projection attached to a slave segment
  // which overlaps with the master side, Lagrange multipliers have to be
  // introduced. This is done by checking all nodes without a projection
  // whether they are attached to some slave segment on which another node
  // HAS a projection. If this case is found, a pseudo ProjectedNode is
  // introduced for that node.
  for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) {
    Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second;
    // do only my own nodes

    // don't do anything on nodes that already have a projection
    if (snode->GetProjectedNode() != Teuchos::null) continue;

    // get segments adjacent to this node
    int nseg                                          = snode->Nseg();
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = snode->Segments();
    // loop segments and check for other nodes with projection
    bool foundit = false;
    for (int i = 0; i < nseg; ++i) {
      int nnode                                       = segs[i]->Nnode();
      MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)** nodes = segs[i]->Nodes();
      for (int j = 0; j < nnode; ++j)
        if (nodes[j]->GetProjectedNode() != Teuchos::null)
          if (nodes[j]->GetProjectedNode()->Segment()) {
            foundit = true;
            break;
          }
      if (foundit) break;
    }
    if (foundit) {
#if 0
      std::cout << "Node without projection:\n" << *snode;        
      std::cout << "...get's lagrange multipliers\n\n";
#endif
      MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
          new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
              *snode, NULL, NULL);
      snode->SetProjectedNode(pnode);
      snode->SetGap(0.);
    }
  }
#endif

  return true;
}
    InterfaceT)::ProjectNodes_MastertoSlave_Orthogonal()
{
  if (!IsComplete()) {
    std::stringstream oss;
    oss << "***ERR*** "
           "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n"
        << "***ERR*** Complete() not called on interface " << Id() << "\n"
        << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
    throw MoertelT::ReportError(oss);
  }
  if (lcomm_ == Teuchos::null) return true;

  int mside = MortarSide();
  int sside = OtherSide(mside);

  // iterate over all master nodes and project those belonging to me
  std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator
      mcurr;
  for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) {
    Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second;
    if (NodePID(mnode->Id()) != lcomm_->getRank()) continue;

    const double*                                         mx = mnode->XCoords();
    double                                                mindist = 1.0e+20;
    Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> closenode =
        Teuchos::null;

    // find a node on the slave side that is closest to me
    std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::
        iterator scurr;
    for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) {
      Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode =
          scurr->second;
      const double* sx = snode->XCoords();

      // build distance | snode->XCoords() - mnode->XCoords() |
      double dist = 0.0;
      for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]);
      dist = sqrt(dist);
      if (dist < mindist) {
        mindist   = dist;
        closenode = snode;
      }
    }
    if (closenode == Teuchos::null) {
      std::stringstream oss;
      oss << "***ERR*** "
             "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n"
          << "***ERR*** Weired: for master node " << mnode->Id()
          << " no closest master node found\n"
          << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      throw MoertelT::ReportError(oss);
    }

    // get segments attached to closest node closenode
    int nseg                                          = closenode->Nseg();
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = closenode->Segments();

    // create a projection operator
    MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT)
        projector(IsOneDimensional(), OutLevel());

    // loop these segments and find best projection
    double bestdist[2];
    double bestgap = 0.0, gap;
    bestdist[0] = bestdist[1]                           = 1.0e+20;
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)* bestseg = NULL;
    for (int i = 0; i < nseg; ++i) {
      // project the master node orthogonally on the slave segment
      double xi[2];
      xi[0] = xi[1] = 0.0;
      projector.ProjectNodetoSegment_SegmentOrthogonal(
          *mnode, *(segs[i]), xi, gap);

      // check whether xi is better than previous projection
      if (IsOneDimensional()) {
        if (abs(xi[0]) < abs(bestdist[0])) {
          bestdist[0] = xi[0];
          bestdist[1] = xi[1];
          bestseg     = segs[i];
          bestgap     = gap;
        }
      } else {
        std::stringstream oss;
        oss << "***ERR*** "
               "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n"
            << "***ERR*** not impl. for 3D\n"
            << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
        throw MoertelT::ReportError(oss);
      }

    }  // for (int i=0; i<nseg; ++i)

    // check whether this best projection is good
    bool ok = false;
    if (IsOneDimensional()) {
      if (abs(bestdist[0]) < 1.01) ok = true;
    } else {
      std::stringstream oss;
      oss << "***ERR*** "
             "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n"
          << "***ERR*** not impl. for 3D\n"
          << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      throw MoertelT::ReportError(oss);
    }

    if (ok)  // the projection is good
    {
      // create a projected node and store it in mnode
      MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
          new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
              *mnode, bestdist, bestseg);
      mnode->SetProjectedNode(pnode);
      mnode->SetGap(bestgap);
    } else  // this mnode does not have a valid projection
    {
      if (OutLevel() > 6)
        std::cout << "MoertelT: ***WRN***: Node " << mnode->Id()
                  << " does not have projection\n\n";
      // mnode->SetProjectedNode(NULL);
    }
  }  // for (mcurr=rnode_[mside].begin(); mcurr!=rnode_[mside].end(); ++mcurr)

  // loop all master nodes again and make projection redundant
  int                 bsize = 4 * rnode_[mside].size();
  std::vector<double> bcast(bsize);
  for (int proc = 0; proc < lcomm_->getSize(); ++proc) {
    int blength = 0;
    if (proc == lcomm_->getRank()) {
      for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end();
           ++mcurr) {
        Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode =
            mcurr->second;
        if (proc != NodePID(mnode->Id()))
          continue;  // cannot have a projection on a node i don't own
        Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)> pnode =
            mnode->GetProjectedNode();
        if (pnode == Teuchos::null)
          continue;  // this node does not have a projection
        const double* xi = pnode->Xi();
        bcast[blength]   = (double)pnode->Id();
        ++blength;
        bcast[blength] = (double)pnode->Segment()->Id();
        ++blength;
        bcast[blength] = xi[0];
        ++blength;
        bcast[blength] = xi[1];
        ++blength;
        bcast[blength] = pnode->Gap();
        ++blength;
      }  // for (mcurr=rnode_[mside].begin(); mcurr!=rnode_[mside].end();
         // ++mcurr)
      if (blength > bsize) {
        std::stringstream oss;
        oss << "***ERR*** "
               "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n"
            << "***ERR*** Overflow in communication buffer occured\n"
            << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
        throw MoertelT::ReportError(oss);
      }
    }  // if (proc==lComm()->MyPID())
    Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength);
    Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]);
    if (proc != lcomm_->getRank()) {
      int i;
      for (i = 0; i < blength;) {
        int nid = (int)bcast[i];
        ++i;
        int sid = (int)bcast[i];
        ++i;
        double* xi = &bcast[i];
        ++i;
        ++i;
        double gap = bcast[i];
        ++i;
        Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode =
            GetNodeView(nid);
        Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg =
            GetSegmentView(sid);
        if (mnode == Teuchos::null || seg == Teuchos::null) {
          std::stringstream oss;
          oss << "***ERR*** "
                 "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n"
              << "***ERR*** Cannot get view of node or segment\n"
              << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
          throw MoertelT::ReportError(oss);
        }
        MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
            new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
                *mnode, xi, seg.get());
        mnode->SetProjectedNode(pnode);
        mnode->SetGap(gap);
      }
      if (i != blength) {
        std::stringstream oss;
        oss << "***ERR*** "
               "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n"
            << "***ERR*** Mismatch in dimension of recv buffer: " << i
            << " != " << blength << "\n"
            << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
        throw MoertelT::ReportError(oss);
      }
    }  // if (proc!=lComm()->MyPID())
  }    // for (int proc=0; proc<lComm()->NumProc(); ++proc)
  bcast.clear();

  return true;
}
    InterfaceT)::ProjectNodes_MastertoSlave_NormalField()
{
  if (!IsComplete()) {
    std::stringstream oss;
    oss << "***ERR*** "
           "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n"
        << "***ERR*** Complete() not called on interface " << Id() << "\n"
        << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
    throw MoertelT::ReportError(oss);
  }
  if (lcomm_ == Teuchos::null) return true;

  int mside = MortarSide();
  int sside = OtherSide(mside);

  // iterate over all nodes of the master side and project those belonging to me
  std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator
      mcurr;
  for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) {
    Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second;
    if (NodePID(mnode->Id()) != lcomm_->getRank()) continue;

    const double*                   mx        = mnode->XCoords();
    double                          mindist   = 1.0e+20;
    Teuchos::RCP<MoertelT::(NodeT)> closenode = Teuchos::null;

    // find a node on the slave side that is closest to me
    std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::
        iterator scurr;
    for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) {
      Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode =
          scurr->second;
      const double* sx = snode->XCoords();

      // build distance | snode->XCoords() - mnode->XCoords() |
      double dist = 0.0;
      for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]);
      dist = sqrt(dist);
      if (dist < mindist) {
        mindist   = dist;
        closenode = snode;
      }
    }
    if (closenode == Teuchos::null) {
      std::stringstream oss;
      oss << "***ERR*** "
             "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n"
          << "***ERR*** Weired: for master node " << mnode->Id()
          << " no closest master node found\n"
          << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      throw MoertelT::ReportError(oss);
    }

#if 0
    std::cout << "snode     " << *mnode;
    std::cout << "closenode " << *closenode;
#endif

    // get segments attached to closest node closenode
    int nseg                                          = closenode->Nseg();
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = closenode->Segments();

    // create a projection operator
    MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT)
        projector(IsOneDimensional(), OutLevel());

    // loop these segments and find best projection
    double       bestdist[2];
    const double tol     = 0.2;
    double       bestgap = 0.0, gap;
    bestdist[0] = bestdist[1]                           = 1.0e+20;
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)* bestseg = NULL;
    for (int i = 0; i < nseg; ++i) {
      // project the master node on the slave segment along the segments
      // interpolated normal field
      double xi[2];
      xi[0] = xi[1] = 0.0;
      projector.ProjectNodetoSegment_SegmentNormal(*mnode, *(segs[i]), xi, gap);

      // check whether xi is better then previous projections
      if (IsOneDimensional()) {
        if (abs(xi[0]) < abs(bestdist[0])) {
          bestdist[0] = xi[0];
          bestdist[1] = xi[1];
          bestseg     = segs[i];
          bestgap     = gap;
        }
      } else {
        double third = 1. / 3.;
        // it's 'inside' with some tolerance
        if (xi[0] <= 1. + tol && xi[1] <= abs(1. - xi[0]) + tol &&
            xi[0] >= 0. - tol && xi[1] >= 0. - tol) {
          // it's better in both directions
          if (sqrt((xi[0] - third) * (xi[0] - third)) <
                  sqrt((bestdist[0] - third) * (bestdist[0] - third)) &&
              sqrt((xi[1] - third) * (xi[1] - third)) <
                  sqrt((bestdist[1] - third) * (bestdist[1] - third))) {
            bestdist[0] = xi[0];
            bestdist[1] = xi[1];
            bestseg     = segs[i];
            bestgap     = gap;
          }
          // it's better in one direction and 'in' in the other
          else if (
              (sqrt((xi[0] - third) * (xi[0] - third)) <
                   sqrt((bestdist[0] - third) * (bestdist[0] - third)) &&
               xi[1] <= abs(1. - xi[0]) + tol && xi[1] >= 0. - tol) ||
              (sqrt((xi[1] - third) * (xi[1] - third)) <
                   sqrt((bestdist[1] - third) * (bestdist[1] - third)) &&
               xi[0] <= 1. + tol && xi[0] >= 0. - tol)) {
            bestdist[0] = xi[0];
            bestdist[1] = xi[1];
            bestseg     = segs[i];
            bestgap     = gap;
          }
        }
      }
    }  // for (int i=0; i<nseg; ++i)

    // check whether the bestseg/bestdist are inside that segment
    // (with some tolerance of 20%)
    bool ok = false;
    if (IsOneDimensional()) {
      if (abs(bestdist[0]) < 1.1) ok = true;
    } else {
      if (bestdist[0] <= 1. + tol &&
          bestdist[1] <= abs(1. - bestdist[0]) + tol &&
          bestdist[0] >= 0. - tol && bestdist[1] >= 0. - tol)
        ok = true;
    }

    if (ok)  // the projection is good
    {
      // build the interpolated normal and overwrite the mnode normal with -n
      int nsnode                                       = bestseg->Nnode();
      MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)** snodes = bestseg->Nodes();
      std::vector<double> val(nsnode);
      bestseg->EvaluateFunction(0, bestdist, &val[0], nsnode, NULL);
      double NN[3];
      NN[0] = NN[1] = NN[2] = 0.0;
      for (int i = 0; i < nsnode; ++i) {
        const double* Normal = snodes[i]->Normal();
        for (int j = 0; j < 3; ++j) NN[j] -= val[i] * Normal[j];
      }
      val.clear();
      mnode->SetN(NN);

      // create projected node and store it in mnode
      MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
          new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
              *mnode, bestdist, bestseg);
      mnode->SetProjectedNode(pnode);
      mnode->SetGap(bestgap);
    } else  // this mnode does not have a valid projection
    {
      if (OutLevel() > 6)
        std::cout << "MoertelT: ***WRN***: Projection m->s: Node "
                  << mnode->Id() << " does not have projection\n";
      mnode->SetProjectedNode(NULL);
    }
  }  // for (scurr=rnode_[mside].begin(); scurr!=rnode_[mside].end(); ++scurr)

  // loop all master nodes again and make the projection and the new normal
  // redundant
  int                 bsize = 7 * rnode_[mside].size();
  std::vector<double> bcast(bsize);
  for (int proc = 0; proc < lcomm_->getSize(); ++proc) {
    int blength = 0;
    if (proc == lcomm_->getRank()) {
      for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end();
           ++mcurr) {
        Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode =
            mcurr->second;
        if (proc != NodePID(mnode->Id()))
          continue;  // cannot have a projection on a node i don't own
        Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)> pnode =
            mnode->GetProjectedNode();
        if (pnode == Teuchos::null)
          continue;  // this node does not have a projection
        const double* xi     = pnode->Xi();
        const double* Normal = mnode->Normal();
        bcast[blength]       = (double)pnode->Id();
        ++blength;
        if (pnode->Segment())
          bcast[blength] = (double)pnode->Segment()->Id();
        else
          bcast[blength] = -0.1;
        ++blength;
        bcast[blength] = xi[0];
        ++blength;
        bcast[blength] = xi[1];
        ++blength;
        bcast[blength] = Normal[0];
        ++blength;
        bcast[blength] = Normal[1];
        ++blength;
        bcast[blength] = Normal[2];
        ++blength;
        bcast[blength] = pnode->Gap();
        ++blength;
      }
      if (blength > bsize) {
        std::stringstream oss;
        oss << "***ERR*** "
               "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n"
            << "***ERR*** Overflow in communication buffer occured\n"
            << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
        throw MoertelT::ReportError(oss);
      }
    }
    Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength);
    Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]);
    if (proc != lcomm_->getRank()) {
      int i;
      for (i = 0; i < blength;) {
        int nid = (int)bcast[i];
        ++i;
        double sid = bcast[i];
        ++i;
        double* xi = &bcast[i];
        ++i;
        ++i;
        double* n = &bcast[i];
        ++i;
        ++i;
        ++i;
        double gap = bcast[i];
        ++i;
        Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode =
            GetNodeView(nid);
        Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg =
            Teuchos::null;
        if (sid != -0.1) seg = GetSegmentView((int)sid);
        if (mnode == Teuchos::null) {
          std::stringstream oss;
          oss << "***ERR*** "
                 "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:"
                 "\n"
              << "***ERR*** Cannot get view of node\n"
              << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
          throw MoertelT::ReportError(oss);
        }
        mnode->SetN(n);
        MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
            new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
                *mnode, xi, seg.get());
        mnode->SetProjectedNode(pnode);
        mnode->SetGap(gap);
      }
      if (i != blength) {
        std::stringstream oss;
        oss << "***ERR*** "
               "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n"
            << "***ERR*** Mismatch in dimension of recv buffer\n"
            << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
        throw MoertelT::ReportError(oss);
      }
    }
  }  // for (int proc=0; proc<lComm()->NumProc(); ++proc)
  bcast.clear();

  return true;
}
    InterfaceT)::ProjectNodes_SlavetoMaster_NormalField()
{
  if (!IsComplete()) {
    std::stringstream oss;
    oss << "***ERR*** "
           "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n"
        << "***ERR*** Complete() not called on interface " << Id() << "\n"
        << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
    throw MoertelT::ReportError(oss);
  }
  if (lcomm_ == Teuchos::null) return true;

  int mside = MortarSide();
  int sside = OtherSide(mside);

  // iterate over all nodes of the slave side and project those belonging to me
  std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator
      scurr;
  for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) {
    Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second;
    if (NodePID(snode->Id()) != lcomm_->getRank()) continue;

    const double*                                         sx = snode->XCoords();
    double                                                mindist = 1.0e+20;
    Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> closenode =
        Teuchos::null;

    // find a node on the master side, that is closest to me
    std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::
        iterator mcurr;
    for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) {
      Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode =
          mcurr->second;
      const double* mx = mnode->XCoords();

      // build distance | mnode->XCoords() - snode->XCoords() |
      double dist = 0.0;
      for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]);
      dist = sqrt(dist);
      if (dist <= mindist) {
        mindist   = dist;
        closenode = mnode;
      }
      std::cout << "snode " << snode->Id() << " mnode " << mnode->Id()
                << " mindist " << mindist << " dist " << dist << std::endl;
    }
    if (closenode == Teuchos::null) {
      std::stringstream oss;
      oss << "***ERR*** "
             "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n"
          << "***ERR*** Weired: for slave node " << snode->Id()
          << " no closest master node found\n"
          << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      throw MoertelT::ReportError(oss);
    }

#if 0
    std::cout << "snode     " << *snode;
    std::cout << "closenode " << *closenode;
#endif

    // get segments attached to closest node cnode
    int nseg                                          = closenode->Nseg();
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = closenode->Segments();

    // create a projection-iterator
    MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT)
        projector(IsOneDimensional(), OutLevel());

    // finding a good geometric projection is somehow
    // critical. We work with some tolerance here and pick the 'best'
    // out of all acceptable projections made
    // loop these segments and project onto them along snode's normal vector
    double       bestdist[2];
    double       gap, bestgap = 0.0;
    const double tol = 0.2;
    bestdist[0] = bestdist[1]                           = 1.0e+20;
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)* bestseg = NULL;
    for (int i = 0; i < nseg; ++i) {
      // project the slave node onto that master segment
      double xi[2];
      xi[0] = xi[1] = 0.0;
      projector.ProjectNodetoSegment_NodalNormal(*snode, *(segs[i]), xi, gap);

      // check whether xi is better then previous projections
      if (IsOneDimensional())  // 2D case
      {
        if (abs(xi[0]) < abs(bestdist[0])) {
          bestdist[0] = xi[0];
          bestdist[1] = xi[1];
          bestseg     = segs[i];
          bestgap     = gap;
        }
      } else  // 3D case
      {
        double third = 1. / 3.;
        // it's 'inside' with some tolerance
        if (xi[0] <= 1. + tol && xi[1] <= abs(1. - xi[0]) + tol &&
            xi[0] >= 0. - tol && xi[1] >= 0. - tol) {
          // it's better in both directions
          if (sqrt((xi[0] - third) * (xi[0] - third)) <
                  sqrt((bestdist[0] - third) * (bestdist[0] - third)) &&
              sqrt((xi[1] - third) * (xi[1] - third)) <
                  sqrt((bestdist[1] - third) * (bestdist[1] - third))) {
            bestdist[0] = xi[0];
            bestdist[1] = xi[1];
            bestseg     = segs[i];
            bestgap     = gap;
          }
          // it's better in one direction and 'in' in the other
          else if (
              (sqrt((xi[0] - third) * (xi[0] - third)) <
                   sqrt((bestdist[0] - third) * (bestdist[0] - third)) &&
               xi[1] <= abs(1. - xi[0]) + tol && xi[1] >= 0. - tol) ||
              (sqrt((xi[1] - third) * (xi[1] - third)) <
                   sqrt((bestdist[1] - third) * (bestdist[1] - third)) &&
               xi[0] <= 1. + tol && xi[0] >= 0. - tol)) {
            bestdist[0] = xi[0];
            bestdist[1] = xi[1];
            bestseg     = segs[i];
            bestgap     = gap;
          }
        }
      }
    }  // for (int i=0; i<nseg; ++i)

    // check whether the bestseg and bestdist are inside the segment
    // (with some tolerance of 20%)
    bool ok = false;
    if (IsOneDimensional()) {
      if (abs(bestdist[0]) < 1.2) ok = true;
    } else {
      if (bestdist[0] <= 1. + tol &&
          bestdist[1] <= abs(1. - bestdist[0]) + tol &&
          bestdist[0] >= 0. - tol && bestdist[1] >= 0. - tol)
        ok = true;
    }

    if (ok)  // the projection is good
    {
      // create a projected node and store it in snode
      MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
          new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
              *snode, bestdist, bestseg);
      snode->SetProjectedNode(pnode);
      snode->SetGap(bestgap);
    } else {
      if (OutLevel() > 6)
        std::cout << "MoertelT: ***WRN***: Projection s->m: Node "
                  << snode->Id() << " does not have projection\n";
      snode->SetProjectedNode(NULL);
    }
  }  // for (scurr=rnode_[sside].begin(); scurr!=rnode_[sside].end(); ++scurr)
  lcomm_->barrier();

  // loop all slave nodes again and make the projections redundant
  std::vector<double> bcast(4 * rnode_[sside].size());
  for (int proc = 0; proc < lcomm_->getSize(); ++proc) {
    int blength = 0;
    if (proc == lcomm_->getRank()) {
      for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end();
           ++scurr) {
        Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode =
            scurr->second;
        if (proc != NodePID(snode->Id()))
          continue;  // I cannot have a projection on a node not owned by me
        Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)> pnode =
            snode->GetProjectedNode();
        if (pnode == Teuchos::null)
          continue;  // this node does not have a projection
        const double* xi = pnode->Xi();
        bcast[blength]   = (double)pnode->Id();
        ++blength;
        if (pnode->Segment())
          bcast[blength] = (double)pnode->Segment()->Id();
        else
          bcast[blength] = -0.1;  // indicating this node does not have
                                  // projection but lagrange multipliers
        ++blength;
        bcast[blength] = xi[0];
        ++blength;
        bcast[blength] = xi[1];
        ++blength;
        bcast[blength] = pnode->Gap();
        ++blength;
      }
      if (blength > (int)(4 * rnode_[sside].size())) {
        std::stringstream oss;
        oss << "***ERR*** "
               "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n"
            << "***ERR*** Overflow in communication buffer occured\n"
            << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
        throw MoertelT::ReportError(oss);
      }
    }
    Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength);
    Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]);
    if (proc != lcomm_->getRank()) {
      int i;
      for (i = 0; i < blength;) {
        int nid = (int)bcast[i];
        ++i;
        double sid = bcast[i];
        ++i;
        double* xi = &bcast[i];
        ++i;
        ++i;
        double gap = bcast[i];
        ++i;
        Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode =
            GetNodeView(nid);
        Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg =
            Teuchos::null;
        if (sid != -0.1) seg = GetSegmentView((int)sid);
        if (snode == Teuchos::null) {
          std::stringstream oss;
          oss << "***ERR*** "
                 "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:"
                 "\n"
              << "***ERR*** Cannot get view of node\n"
              << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
          throw MoertelT::ReportError(oss);
        }
        MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
            new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
                *snode, xi, seg.get());
        snode->SetProjectedNode(pnode);
        snode->SetGap(gap);
      }
      if (i != blength) {
        std::stringstream oss;
        oss << "***ERR*** "
               "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n"
            << "***ERR*** Mismatch in dimension of recv buffer\n"
            << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
        throw MoertelT::ReportError(oss);
      }
    }
  }  // for (int proc=0; proc<lComm()->NumProc(); ++proc)
  bcast.clear();
  lcomm_->barrier();

#if 1
  // Postprocess the projections
  // The slave side of the interface might be larger then the master side
  // of the interface so not all slave nodes have a projection.
  // For those slave nodes without a projection attached to a slave segment
  // which overlaps with the master side, Lagrange multipliers have to be
  // introduced. This is done by checking all nodes without a projection
  // whether they are attached to some slave segment on which another node
  // HAS a projection. If this case is found, a pseudo ProjectedNode is
  // introduced for that node.
  for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) {
    Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second;

    // don't do anything on nodes that already have a projection
    if (snode->GetProjectedNode() != Teuchos::null) continue;

    // get segments adjacent to this node
    int nseg                                          = snode->Nseg();
    MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = snode->Segments();

    // loop segments and check for other nodes with projection
    bool foundit = false;
    for (int i = 0; i < nseg; ++i) {
      int nnode                                       = segs[i]->Nnode();
      MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)** nodes = segs[i]->Nodes();
      for (int j = 0; j < nnode; ++j)
        if (nodes[j]->GetProjectedNode() != Teuchos::null)
          if (nodes[j]->GetProjectedNode()->Segment()) {
            foundit = true;
            break;
          }
      if (foundit) break;
    }

    if (foundit) {
#if 1
      std::cout << "Node without projection:\n" << *snode;
      std::cout << "...get's lagrange multipliers\n\n";
#endif
      MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode =
          new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)(
              *snode, NULL, NULL);
      snode->SetProjectedNode(pnode);
      snode->SetGap(0.);
    }
  }  // for (scurr=rnode_[sside].begin(); scurr!=rnode_[sside].end(); ++scurr)
#endif

  return true;
}
예제 #17
0
double SpringEstimator::updateNArm(double timeStep, int nrIter)
{
  for(int iter = 0; iter < nrIter; ++iter)
  {
    updateArmsData();

    // compute task 1 and 2 error and jacobian
    // (end effector position/orientation error)
    int dof = 0;
    for(std::size_t i = 1; i < arms_.size(); ++i)
    {
      dof += arms_[i-1].jac.dof();
      const sva::PTransformd& arm0 =
          arms_[0].mbc.bodyPosW[arms_[0].endEffectorIndex];
      const sva::PTransformd& armi =
          arms_[i].mbc.bodyPosW[arms_[i].endEffectorIndex];

      tasks_[0].err.segment((i-1)*3, 3).noalias() =
          arm0.translation() - armi.translation();
      tasks_[1].err.segment((i-1)*3, 3).noalias() =
          sva::rotationError(armi.rotation(), arm0.rotation(), 1e-7);

      tasks_[0].jac.block((i-1)*3, 0, 3, arms_[0].jac.dof()).noalias() =
          arms_[0].jacMat.block(3, 0, 3, arms_[0].jac.dof());
      tasks_[1].jac.block((i-1)*3, 0, 3, arms_[0].jac.dof()).noalias() =
          arms_[0].jacMat.block(0, 0, 3, arms_[0].jac.dof());

      tasks_[0].jac.block((i-1)*3, dof, 3, arms_[i].jac.dof()).noalias() =
          -arms_[i].jacMat.block(3, 0, 3, arms_[i].jac.dof());
      tasks_[1].jac.block((i-1)*3, dof, 3, arms_[i].jac.dof()).noalias() =
          -arms_[i].jacMat.block(0, 0, 3, arms_[i].jac.dof());
    }

    // compute task 3 error and jacobian
    // minimize distance between the arm 0 end effector and the target
    const sva::PTransformd& arm0 =
        arms_[0].mbc.bodyPosW[arms_[0].endEffectorIndex];
    tasks_[2].err.noalias() = sva::rotationError(target_, arm0.rotation(), 1e-7);
    tasks_[2].jac.block(0, 0, 3, arms_[0].jac.dof()).noalias() =
        arms_[0].jacMat.block(0, 0, 3, arms_[0].jac.dof());

    for(std::size_t i = 0; i < jTargetData_.size(); ++i)
    {
      const JointTargetData& jtd = jTargetData_[i];
      tasks_[3].err(i) = q_(jtd.jointIndexInQ) - jtd.target;
    }

    // solve all the tasks
    solveT1(tasks_[0], lstsqMinTol_, lstsqRelTol_);
    for(std::size_t i = 1; i < tasks_.size(); ++i)
    {
      projector(tasks_[i - 1], projs_[i - 1], projs_[i], projMinTol_,
                projRelTol_);
      solveTN(tasks_[i - 1], projs_[i], tasks_[i], lstsqMinTol_, lstsqRelTol_);
    }

    qd_.noalias() = tasks_.back().qd;
    q_.noalias() -= qd_*timeStep;
  }

  return 0.;
}
예제 #18
0
void SkyMap::mousePressEvent( QMouseEvent *e ) {
    KStars* kstars = KStars::Instance();

    if ( ( e->modifiers() & Qt::ControlModifier ) && (e->button() == Qt::LeftButton) ) {
        ZoomRect.moveCenter( e->pos() );
        setZoomMouseCursor();
        update(); //refresh without redrawing skymap
        return;
    }

    // if button is down and cursor is not moved set the move cursor after 500 ms
    QTimer::singleShot(500, this, SLOT (setMouseMoveCursor()));

    // break if point is unusable
    if ( projector()->unusablePoint( e->pos() ) )
        return;

    if ( !midMouseButtonDown && e->button() == Qt::MidButton ) {
        y0 = 0.5*height() - e->y();  //record y pixel coordinate for middle-button zooming
        midMouseButtonDown = true;
    }

    if ( !mouseButtonDown ) {
        if ( e->button() == Qt::LeftButton ) {
            mouseButtonDown = true;
        }

        //determine RA, Dec of mouse pointer
        m_MousePoint = projector()->fromScreen( e->pos(), data->lst(), data->geo()->lat() );
        setClickedPoint( &m_MousePoint );

        //Find object nearest to clickedPoint()
        double maxrad = 1000.0/Options::zoomFactor();
        SkyObject* obj = data->skyComposite()->objectNearest( clickedPoint(), maxrad );
        setClickedObject( obj );
        if( obj )
            setClickedPoint( obj );

        switch( e->button() ) {
        case Qt::LeftButton:
            if( kstars ) {
                QString name;
                if( clickedObject() )
                    name = clickedObject()->translatedLongName();
                else
                    name = i18n( "Empty sky" );
                kstars->statusBar()->changeItem(name, 0 );
            }
            break;
        case Qt::RightButton:
            if( rulerMode ) {
                // Compute angular distance.
                slotEndRulerMode();
            } else {
                // Show popup menu
                if( clickedObject() ) {
                    clickedObject()->showPopupMenu( pmenu, QCursor::pos() );
                } else {
                    pmenu->createEmptyMenu( clickedPoint() );
                    pmenu->popup( QCursor::pos() );
                }
            }
            break;
        default: ;
        }
    }
}
예제 #19
0
void u_iii_forcing(struct Field fldi, double dt) {
	double *x, *y, *z;		 	
	int i,j,k;

	x = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (x == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for x allocation");
	
	y = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (y == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for y allocation");
	
	z = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (z == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for z allocation");

	// Initialize the arrays
	
	for(i = 0 ; i < NX/NPROC ; i++) {
		for(j = 0 ; j < NY ; j++) {
			for(k = 0 ; k < NZ ; k++) {
				x[k + (NZ + 2) * j + (NZ + 2) * NY * i] = - param.lx / 2 + (param.lx * (i + rank * NX / NPROC)) / NX;
				y[k + (NZ + 2) * j + (NZ + 2) * NY * i] = - param.ly / 2 + (param.ly * j ) / NY;
				z[k + (NZ + 2) * j + (NZ + 2) * NY * i] = - param.lz / 2 + (param.lz * k ) / NZ;
			}
		}
	}
	
	// Initialize the extra points (k=NZ and k=NZ+1) to zero to prevent stupid things from happening...
	for(i = 0 ; i < NX/NPROC ; i++) {
		for(j = 0 ; j < NY ; j++) {
			for(k = NZ ; k < NZ + 2 ; k++) {
				x[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				y[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				z[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;

			}
		}
	}
	
	// Init work array to zero
	for(i = 0 ; i < NX/NPROC ; i++) {
		for(j = 0 ; j < NY ; j++) {
			for(k = 0 ; k < NZ + 2 ; k++) {
				wr4[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				wr5[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				wr6[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
   			}
		}
   }

    /*******************************************************************
	** This part can be modified              **************************
	********************************************************************/
	
	// The velocity field vx,vy,vz is stored in wr1,wr2,wr3
   	for(i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
     
        wr4[i] = param.modified_ABC_flow_D*(
                    cos(x[i]/param.modified_ABC_flow_m)*(
                        param.modified_ABC_flow_A*param.modified_ABC_flow_kz*sin(z[i] /(double) param.modified_ABC_flow_kz ) +
                        param.modified_ABC_flow_C*param.modified_ABC_flow_ky*cos(y[i] /(double) param.modified_ABC_flow_ky)
                    ) + 
                    sin(x[i]/param.modified_ABC_flow_m)/param.modified_ABC_flow_m*(
                        0
                    )                                         
                ); 
        wr5[i] = param.modified_ABC_flow_D*(
                    cos(x[i]/param.modified_ABC_flow_m)*(
                        param.modified_ABC_flow_B*param.modified_ABC_flow_kx*sin(x[i] /(double) param.modified_ABC_flow_kx ) +
                        param.modified_ABC_flow_A*param.modified_ABC_flow_kz*cos(z[i] /(double) param.modified_ABC_flow_kz)
                    ) + 
                    sin(x[i]/param.modified_ABC_flow_m)/param.modified_ABC_flow_m*(
                        param.modified_ABC_flow_B*cos(x[i] /(double) param.modified_ABC_flow_kx) + 
                        param.modified_ABC_flow_C*sin(y[i] /(double) param.modified_ABC_flow_ky)
                    )                                         
                );
        wr6[i] = param.modified_ABC_flow_D*(
                    cos(x[i]/param.modified_ABC_flow_m)*(
                        param.modified_ABC_flow_C*param.modified_ABC_flow_ky*sin(y[i] /(double) param.modified_ABC_flow_ky ) +
                        param.modified_ABC_flow_B*param.modified_ABC_flow_kx*cos(x[i] /(double) param.modified_ABC_flow_kx)
                    ) + 
                    sin(x[i]/param.modified_ABC_flow_m)/param.modified_ABC_flow_m*(
                        -param.modified_ABC_flow_A*cos(z[i] /(double) param.modified_ABC_flow_kz) + 
                        -param.modified_ABC_flow_B*sin(x[i] /(double) param.modified_ABC_flow_kx)
                    )                                         
                );
    }
    gfft_r2c(wr4);
	gfft_r2c(wr5);
    gfft_r2c(wr6);
	
    for(i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		w4[i] = w4[i] * mask[i];
		w5[i] = w5[i] * mask[i];
		w6[i] = w6[i] * mask[i];
    }   

	for( i = 0; i < NX_COMPLEX/NPROC; i++) {
		for( j = 0; j < NY_COMPLEX; j++) {
			for( k = 0; k < NZ_COMPLEX; k++) {
				fldi.vx[ IDX3D ] +=  w4[ IDX3D ] * (1 - exp(-nu*k2t[IDX3D]*dt)) ;
				fldi.vy[ IDX3D ] +=  w5[ IDX3D ] * (1 - exp(-nu*k2t[IDX3D]*dt)) ;
				fldi.vz[ IDX3D ] +=  w6[ IDX3D ] * (1 - exp(-nu*k2t[IDX3D]*dt)) ;
			}
		}
	}

#ifdef U_III_FORCING_EXTRA
    gfft_c2r_t(w4);
	gfft_c2r_t(w5);
	gfft_c2r_t(w6);

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)	
#endif
	for( i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
		wr10[i] = wr4[i] * wr4[i] / ((double) NTOTAL*NTOTAL);
		wr11[i] = wr5[i] * wr5[i] / ((double) NTOTAL*NTOTAL);
#ifndef WITH_2D
		wr12[i] = wr6[i] * wr6[i] / ((double) NTOTAL*NTOTAL);
#endif
		wr7[i] = wr4[i] * wr5[i] / ((double) NTOTAL*NTOTAL);
		wr8[i] = wr4[i] * wr6[i] / ((double) NTOTAL*NTOTAL);
		wr9[i] = wr5[i] * wr6[i] / ((double) NTOTAL*NTOTAL);
	}
	
	gfft_r2c_t(wr10);
	gfft_r2c_t(wr11);
#ifndef WITH_2D
	gfft_r2c_t(wr12);
#endif
	gfft_r2c_t(wr7);
	gfft_r2c_t(wr8);
	gfft_r2c_t(wr9);

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)	
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		fldi.vx[i] +=  I * mask[i] / (nu * k2t) * (1 - exp(-nu*k2t[IDX3D]*dt)) * (
					kxt[i] * w10[i] + ky[i] * w7[i] + kz[i] * w8[i] );
		fldi.vy[i] +=  I * mask[i] / (nu * k2t) * (1 - exp(-nu*k2t[IDX3D]*dt)) * (
					kxt[i] * w7[i] + ky[i] * w11[i] + kz[i] * w9[i] );
		fldi.vz[i] +=  I * mask[i] / (nu * k2t) * (1 - exp(-nu*k2t[IDX3D]*dt)) * (
					kxt[i] * w8[i] + ky[i] * w9[i] + kz[i] * w12[i] );	// since kz=0 in 2D, kz*w6 gives 0, even if w6 is some random array
	}

#endif

	projector(fldi.vx,fldi.vy,fldi.vz);	
	return;
}
예제 #20
0
void SkyMap::mouseMoveEvent( QMouseEvent *e ) {
    if ( Options::useHoverLabel() ) {
        //Start a single-shot timer to monitor whether we are currently hovering.
        //The idea is that whenever a moveEvent occurs, the timer is reset.  It
        //will only timeout if there are no move events for HOVER_INTERVAL ms
        m_HoverTimer.start( HOVER_INTERVAL );
        QToolTip::hideText();
    }

    //Are we defining a ZoomRect?
    if ( ZoomRect.center().x() > 0 && ZoomRect.center().y() > 0 ) {
        //cancel operation if the user let go of CTRL
        if ( !( e->modifiers() & Qt::ControlModifier ) ) {
            ZoomRect = QRect(); //invalidate ZoomRect
            update();
        } else {
            //Resize the rectangle so that it passes through the cursor position
            QPoint pcenter = ZoomRect.center();
            int dx = abs(e->x() - pcenter.x());
            int dy = abs(e->y() - pcenter.y());
            if ( dx == 0 || float(dy)/float(dx) > float(height())/float(width()) ) {
                //Size rect by height
                ZoomRect.setHeight( 2*dy );
                ZoomRect.setWidth( 2*dy*width()/height() );
            } else {
                //Size rect by height
                ZoomRect.setWidth( 2*dx );
                ZoomRect.setHeight( 2*dx*height()/width() );
            }
            ZoomRect.moveCenter( pcenter ); //reset center

            update();
            return;
        }
    }

    if ( projector()->unusablePoint( e->pos() ) ) return;  // break if point is unusable

    //determine RA, Dec of mouse pointer
    m_MousePoint = projector()->fromScreen( e->pos(), data->lst(), data->geo()->lat() );

    double dyPix = 0.5*height() - e->y();
    if ( midMouseButtonDown ) { //zoom according to y-offset
        float yoff = dyPix - y0;
        if (yoff > 10 ) {
            y0 = dyPix;
            slotZoomIn();
        }
        if (yoff < -10 ) {
            y0 = dyPix;
            slotZoomOut();
        }
    }

    if ( mouseButtonDown ) {
        // set the mouseMoveCursor and set slewing=true, if they are not set yet
        if( !mouseMoveCursor )
            setMouseMoveCursor();
        if( !slewing ) {
            slewing = true;
            stopTracking(); //toggle tracking off
        }

        //Update focus such that the sky coords at mouse cursor remain approximately constant
        if ( Options::useAltAz() ) {
            m_MousePoint.EquatorialToHorizontal( data->lst(), data->geo()->lat() );
            clickedPoint()->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
            dms dAz  = m_MousePoint.az()  - clickedPoint()->az();
            dms dAlt = m_MousePoint.alt() - clickedPoint()->alt();
            focus()->setAz( focus()->az().Degrees() - dAz.Degrees() ); //move focus in opposite direction
            focus()->setAz( focus()->az().reduce() );
            focus()->setAlt(
                KSUtils::clamp( focus()->alt().Degrees() - dAlt.Degrees() , -90.0 , 90.0 ) );
            focus()->HorizontalToEquatorial( data->lst(), data->geo()->lat() );
        } else {
            dms dRA  = m_MousePoint.ra()  - clickedPoint()->ra();
            dms dDec = m_MousePoint.dec() - clickedPoint()->dec();
            focus()->setRA( focus()->ra().Hours() - dRA.Hours() ); //move focus in opposite direction
            focus()->setRA( focus()->ra().reduce() );
            focus()->setDec(
                KSUtils::clamp( focus()->dec().Degrees() - dDec.Degrees() , -90.0 , 90.0 ) );
            focus()->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
        }
        showFocusCoords();

        //redetermine RA, Dec of mouse pointer, using new focus
        m_MousePoint = projector()->fromScreen( e->pos(), data->lst(), data->geo()->lat() );
        setClickedPoint( &m_MousePoint );

        forceUpdate();  // must be new computed

    } else { //mouse button not down
        emit mousePointChanged( &m_MousePoint );
    }
}
예제 #21
0
void forcing(struct Field fldi,
			 double dt) {
			 
// Force random velocity field
	const double kf = 3.0 * M_PI * 2.0;
	const double deltakf = kf * 0.2;
	const double amplitude_forcing = 0.1;

	// Force all the vector
	
	
	int i,j,k;
	int num_force=0;
	int total_num_force;
	double fact;
	double q0;
	
	q0=pow(dt,0.5);
	
	for( i = 0; i < NX_COMPLEX/NPROC; i++) {
		for( j = 0; j < NY_COMPLEX; j++) {
			for( k = 0; k < NZ_COMPLEX; k++) {
				if( (k2t[ IDX3D ]>(kf-deltakf)*(kf-deltakf)) && (k2t[ IDX3D ]<(kf+deltakf)*(kf+deltakf))) {
					w4[ IDX3D ] = amplitude_forcing * mask[IDX3D] * randm() * cexp( I * 2.0*M_PI*randm() ) * NTOTAL*q0;
					w5[ IDX3D ] = amplitude_forcing * mask[IDX3D] * randm() * cexp( I * 2.0*M_PI*randm() ) * NTOTAL*q0;
					w6[ IDX3D ] = amplitude_forcing * mask[IDX3D] * randm() * cexp( I * 2.0*M_PI*randm() ) * NTOTAL*q0;

					if(mask[IDX3D] > 0) num_force++;
				}
				else {
					w4[ IDX3D ] = 0.0;
					w5[ IDX3D ] = 0.0;
					w6[ IDX3D ] = 0.0;
				}
			}
		}
	}
	
  symmetrize_complex(w4);
  if(rank==0) w4[0]=0.0;
  symmetrize_complex(w5);
  if(rank==0) w5[0]=0.0;
  symmetrize_complex(w6);
  if(rank==0) w6[0]=0.0;
  
	// Get the total number of forced scales.
#ifdef MPI_SUPPORT
	MPI_Allreduce( &num_force, &total_num_force, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
#else
	total_num_force=num_force;
#endif
	
	fact=pow(total_num_force,0.5);

	for( i = 0; i < NX_COMPLEX/NPROC; i++) {
		for( j = 0; j < NY_COMPLEX; j++) {
			for( k = 0; k < NZ_COMPLEX; k++) {
				fldi.vx[ IDX3D ] += w4[ IDX3D ] / fact;
				fldi.vy[ IDX3D ] += w5[ IDX3D ] / fact;
				fldi.vz[ IDX3D ] += w6[ IDX3D ] / fact;
			}
		}
	}
	
	projector(fldi.vx,fldi.vy,fldi.vz);
	
	return;
}
예제 #22
0
void timestep( struct Field dfldo,
			   struct Field fldi,
			   const double t,
			   const double tremap,
			   const double dt) {
			   
	int i;
	double complex q0,q1;
	double qr0;
	double S, gamma, epsilon,w;
	double costheta,sintheta;
	int j,k; //AJB

	// This is the timesteping algorithm, solving the physics.

	// Find the shear at time t
#ifdef WITH_SHEAR
#ifdef TIME_DEPENDANT_SHEAR
	S = param.shear * cos(param.omega_shear * t);	// This is the real shear: -dvy/dx
#else
	S = param.shear;
#endif
#endif
#ifdef WITH_ELLIPTICAL_VORTEX //AJB
	gamma = param.gamma;
	epsilon = param.epsilon;
	w = sqrt(gamma*gamma-epsilon*epsilon);
#endif
#ifdef WITH_ROTATION //AJB
	if(param.theta==0.0) {
	  costheta=1.0;
	  sintheta=0.0; //just in case not exact below...
	} else {
	  costheta=cos(param.theta*M_PI/180.0);
	  sintheta=sin(param.theta*M_PI/180.0);
	}
#endif

/* #ifdef ELSASSER_FORMULATION */
/* /\****************************************** */
/* ** ELSASSER variable formulation ********** */
/* ** To be used  */
/* *******************************************\/ */

/* // Solve the MHD equations using Elsasser fields */
/* #ifdef _OPENMP */
/* 	#pragma omp parallel for private(i) schedule(static)	 */
/* #endif */
/* 	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) { */
/* 		w1[i] =  fldi.vx[i]+fldi.bx[i]; */
/* 		w2[i] =  fldi.vy[i]+fldi.by[i]; */
/* 		w3[i] =  fldi.vz[i]+fldi.bz[i]; */
		
/* 		w4[i] =  fldi.vx[i]-fldi.bx[i]; */
/* 		w5[i] =  fldi.vy[i]-fldi.by[i]; */
/* 		w6[i] =  fldi.vz[i]-fldi.bz[i]; */
/* 	} */
	
/* 	// These fields should have no divergence. */
/* 	// When shear is on, however, divergence is conserved up to the timeintegrator precision. */
/* 	// Let's clean it. */
/* 	projector(w1,w2,w3); */
/* 	projector(w4,w5,w6); */

/* 	gfft_c2r_t(w1); */
/* 	gfft_c2r_t(w2); */
/* 	gfft_c2r_t(w3); */
	
/* 	gfft_c2r_t(w4); */
/* 	gfft_c2r_t(w5); */
/* 	gfft_c2r_t(w6); */
	
/* // Compute the Elsasser tensor */

/* #ifdef _OPENMP */
/* 	#pragma omp parallel for private(i) schedule(static)	 */
/* #endif */
/* 	for( i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) { */
/* 		wr7[i]  = wr1[i] * wr4[i] / ((double) NTOTAL*NTOTAL); */
/* 		wr8[i]  = wr1[i] * wr5[i] / ((double) NTOTAL*NTOTAL); */
/* 		wr9[i]  = wr1[i] * wr6[i] / ((double) NTOTAL*NTOTAL); */
/* 		wr10[i] = wr2[i] * wr4[i] / ((double) NTOTAL*NTOTAL); */
/* 		wr11[i] = wr2[i] * wr5[i] / ((double) NTOTAL*NTOTAL); */
/* 		wr12[i] = wr2[i] * wr6[i] / ((double) NTOTAL*NTOTAL); */
/* 		wr13[i] = wr3[i] * wr4[i] / ((double) NTOTAL*NTOTAL); */
/* 		wr14[i] = wr3[i] * wr5[i] / ((double) NTOTAL*NTOTAL); */
/* 		wr15[i] = wr3[i] * wr6[i] / ((double) NTOTAL*NTOTAL); */
/* 	} */
	
/* 	gfft_r2c_t(wr7); */
/* 	gfft_r2c_t(wr8); */
/* 	gfft_r2c_t(wr9); */
/* 	gfft_r2c_t(wr10); */
/* 	gfft_r2c_t(wr11); */
/* 	gfft_r2c_t(wr12); */
/* 	gfft_r2c_t(wr13); */
/* 	gfft_r2c_t(wr14); */
/* 	gfft_r2c_t(wr15); */
	
/* // Compute the volution of the Elssaser fields (u= ik. */
/* #ifdef _OPENMP */
/* 	#pragma omp parallel for private(i) schedule(static)	 */
/* #endif */
/* 	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) { */
/* 		dfldo.vx[i] = - I * 0.5 * mask[i] * ( */
/* 						kxt[i] * ( 2.0 * w7[i]  ) + kyt[i] * ( w8[i] + w10[i]) + kzt[i] * (w9[i]  + w13[i]) ); */
/* 		dfldo.vy[i] = - I * 0.5 * mask[i] * ( */
/* 						kxt[i] * (w10[i] + w8[i]) + kyt[i] * ( 2.0   * w11[i]) + kzt[i] * (w12[i] + w14[i]) ); */
/* 		dfldo.vz[i] = - I * 0.5 * mask[i] * ( */
/* 						kxt[i] * (w13[i] + w9[i]) + kyt[i] * (w14[i] + w12[i]) + kzt[i] * ( 2.0 * w15[i]  ) ); */
		
										
/* 		dfldo.bx[i] = - I * 0.5 * mask[i] * ( */
/* 						                            kyt[i] * ( w8[i] - w10[i]) + kzt[i] * (w9[i]  - w13[i]) ); */
/* 		dfldo.by[i] = - I * 0.5 * mask[i] * ( */
/* 						kxt[i] * (w10[i] - w8[i])                             + kzt[i] * (w12[i] - w14[i]) ); */
/* 		dfldo.bz[i] = - I * 0.5 * mask[i] * ( */
/* 						kxt[i] * (w13[i] - w9[i]) + kyt[i] * (w14[i] - w12[i])  ); */
		

/* 	} */
		
/* // Compute real(U) in case it is used later. */
/* 	for( i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) { */
/* 		wr1[i] = 0.5 * (wr1[i] + wr4[i]); */
/* 		wr2[i] = 0.5 * (wr2[i] + wr5[i]); */
/* 		wr3[i] = 0.5 * (wr3[i] + wr6[i]); */
/* 	} */

/* #else */
/******************************************
** Velocity Self Advection ****************
*******************************************/

		/* Compute the convolution */
#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)	
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		w1[i] =  fldi.vx[i];
		w2[i] =  fldi.vy[i];
		w3[i] =  fldi.vz[i];
	}

	// These fields should have no divergence.
	// When shear is on, however, divergence is conserved up to the timeintegrator precision.
	// Let's clean it.
	projector(w1,w2,w3);
	
	gfft_c2r_t(w1);
	gfft_c2r_t(w2);
	gfft_c2r_t(w3);
	
	/* Compute the convolution for the advection process */
	
#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)	
#endif
	for( i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
		wr4[i] = wr1[i] * wr1[i] / ((double) NTOTAL*NTOTAL);
		wr5[i] = wr2[i] * wr2[i] / ((double) NTOTAL*NTOTAL);
#ifndef WITH_2D
		wr6[i] = wr3[i] * wr3[i] / ((double) NTOTAL*NTOTAL);
#endif
		wr7[i] = wr1[i] * wr2[i] / ((double) NTOTAL*NTOTAL);
		wr8[i] = wr1[i] * wr3[i] / ((double) NTOTAL*NTOTAL);
		wr9[i] = wr2[i] * wr3[i] / ((double) NTOTAL*NTOTAL);
	}
	
	gfft_r2c_t(wr4);
	gfft_r2c_t(wr5);
#ifndef WITH_2D
	gfft_r2c_t(wr6);
#endif
	gfft_r2c_t(wr7);
	gfft_r2c_t(wr8);
	gfft_r2c_t(wr9);

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)	
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
	  dfldo.vx[i] = - I * mask[i] * ( kxt[i] * w4[i] + kyt[i] * w7[i] + kzt[i] * w8[i] );
	  dfldo.vy[i] = - I * mask[i] * ( kxt[i] * w7[i] + kyt[i] * w5[i] + kzt[i] * w9[i] );
	  dfldo.vz[i] = - I * mask[i] * ( kxt[i] * w8[i] + kyt[i] * w9[i] + kzt[i] * w6[i] );	// since kz=0 in 2D, kz*w6 gives 0, even if w6 is some random array

	} 

	if(param.nonlinearoff) { //AJB turn off nonlinearities
	  for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
	    dfldo.vx[i] = 0.0;
	    dfldo.vy[i] = 0.0;
	    dfldo.vz[i] = 0.0;
	  }
	}
	
/* #endif */

/**********************************************
** BOUSSINESQ TERMS (if needed) ***************
***********************************************/

#ifdef BOUSSINESQ
#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		w4[i] = fldi.th[i];
	}
	
	gfft_c2r_t(w4);
		
#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)
#endif
	for( i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
		wr5[i] = wr1[i] * wr4[i] / ((double) NTOTAL*NTOTAL);
		wr6[i] = wr2[i] * wr4[i] / ((double) NTOTAL*NTOTAL);
#ifndef WITH_2D
		wr7[i] = wr3[i] * wr4[i] / ((double) NTOTAL*NTOTAL);
#endif
#ifdef N2PROFILE
		wr8[i] = N2_profile[i] * wr4[i] / ((double) NTOTAL);
#endif
	}
	gfft_r2c_t(wr5);
	gfft_r2c_t(wr6);
#ifndef WITH_2D
	gfft_r2c_t(wr7);
#endif
#ifdef N2PROFILE
	gfft_r2c_t(wr8);
#endif

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
#ifdef VERTSTRAT
#ifdef N2PROFILE
		dfldo.vz[i] -= w8[i] * mask[i];
#else
		//dfldo.vz[i] -= param.N2 * fldi.th[i];
                dfldo.vz[i] += fldi.th[i];
#endif
		dfldo.th[i] = - I*mask[i]*(
			kxt[i]*w5[i]+kyt[i]*w6[i]+kzt[i]*w7[i])
			- param.N2*fldi.vz[i];		
		/* dfldo.th[i] = - I * mask[i] * ( */
		/* 	kxt[i] * w5[i] + kyt[i] * w6[i] + kzt[i] * w7[i]) */
		/* 	+ fldi.vz[i]; */
#else //not vertstrat
#ifdef N2PROFILE
		dfldo.vx[i] -= w8[i] * mask[i];
#else
		//	dfldo.vx[i] -= param.N2 * fldi.th[i];
		dfldo.vx[i] += fldi.th[i];
#endif
		dfldo.th[i] = -I*mask[i]*(
		   kxt[i]*w5[i]+kyt[i]*w6[i]+kzt[i]*w7[i])
			- param.N2*fldi.vx[i];		
/* 		dfldo.th[i] = - I*mask[i]*( */
/* 			kxt[i]*w5[i]+kyt[i]*w6[i]+kzt[i]*w7[i]) */
/* 			+ fldi.vx[i]; */
#endif //vertstrat
	}
	
	
#endif

/*********************************************
**** MHD Terms (if needed)   *****************
*********************************************/
#ifdef MHD
#ifndef ELSASSER_FORMULATION		// If Elssaser is on, MHD are already computed...

// Start with the induction equation
#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		w4[i] =  fldi.bx[i];
		w5[i] =  fldi.by[i];
		w6[i] =  fldi.bz[i];
	}

	// These fields should have no divergence.
	// When shear is on, however, divergence is conserved up to the timeintegrator precision.
	// Let's clean it.
	projector(w4,w5,w6);
	
	gfft_c2r_t(w4);
	gfft_c2r_t(w5);
	gfft_c2r_t(w6);
	
	// (vx,vy,vz) is in w1-w3 and (bx,by,bz) is in (w4-w6). It is now time to compute the emfs in w7-w9...
#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)
#endif
	for( i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
		wr7[i] = (wr2[i] * wr6[i] - wr3[i] * wr5[i]) / ((double) NTOTAL*NTOTAL);
		wr8[i] = (wr3[i] * wr4[i] - wr1[i] * wr6[i]) / ((double) NTOTAL*NTOTAL);
		wr9[i] = (wr1[i] * wr5[i] - wr2[i] * wr4[i]) / ((double) NTOTAL*NTOTAL);
	}

	// Compute the curl of the emf to add in the induction equation.
	
	gfft_r2c_t(wr7);
	gfft_r2c_t(wr8);
	gfft_r2c_t(wr9);

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		dfldo.bx[i] = I * mask[i] * (kyt[i] * w9[i] - kzt[i] * w8[i]);
		dfldo.by[i] = I * mask[i] * (kzt[i] * w7[i] - kxt[i]* w9[i]);
		dfldo.bz[i] = I * mask[i] * (kxt[i]* w8[i] - kyt[i] * w7[i]);

#ifdef WITH_ELLIPTICAL_VORTEX //AJB 02/02/12
		dfldo.bx[i] -= (gamma+epsilon)*fldi.by[i];
		dfldo.by[i] -= -(gamma-epsilon)*fldi.bx[i];
#endif

	}


// Let's do the Lorentz Force
// We already have (bx,by,bz) in w4-w6. No need to compute them again...

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)
#endif
	for( i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
		wr1[i] = wr4[i] * wr4[i] / ((double) NTOTAL*NTOTAL);
		wr2[i] = wr5[i] * wr5[i] / ((double) NTOTAL*NTOTAL);
		wr3[i] = wr6[i] * wr6[i] / ((double) NTOTAL*NTOTAL);
		wr7[i] = wr4[i] * wr5[i] / ((double) NTOTAL*NTOTAL);
		wr8[i] = wr4[i] * wr6[i] / ((double) NTOTAL*NTOTAL);
		wr9[i] = wr5[i] * wr6[i] / ((double) NTOTAL*NTOTAL);
	}


	gfft_r2c_t(wr1);
	gfft_r2c_t(wr2);
	gfft_r2c_t(wr3);
	gfft_r2c_t(wr7);
	gfft_r2c_t(wr8);
	gfft_r2c_t(wr9);

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		dfldo.vx[i] += I * mask[i] * (kxt[i] * w1[i] + kyt[i] * w7[i] + kzt[i] * w8[i]);
		dfldo.vy[i] += I * mask[i] * (kxt[i] * w7[i] + kyt[i] * w2[i] + kzt[i] * w9[i]);
		dfldo.vz[i] += I * mask[i] * (kxt[i] * w8[i] + kyt[i] * w9[i] + kzt[i] * w3[i]);
	}
	
#endif
#endif

/************************************
** SOURCE TERMS  ********************
************************************/

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
#ifdef WITH_ROTATION //AJB modified for tilted rotation in xz-plane
	  dfldo.vx[i]+=2.0*param.omega*fldi.vy[i]*costheta;
	  dfldo.vy[i]-=2.0*param.omega*(fldi.vx[i]*costheta-fldi.vz[i]*sintheta);
	  dfldo.vz[i]-=2.0*param.omega*fldi.vy[i]*sintheta;
#endif
#ifdef WITH_SHEAR
		dfldo.vy[i] += S  * fldi.vx[i];
#ifdef MHD
		dfldo.by[i] -= S * fldi.bx[i];
#endif
#endif
#ifdef WITH_ELLIPTICAL_VORTEX //AJB
		dfldo.vx[i] += (gamma+epsilon)*fldi.vy[i];
		dfldo.vy[i] += -(gamma-epsilon)*fldi.vx[i];
#endif
	}
	
/************************************
** EXPLICIT LINEAR DISSIPATION ******
*************************************/

/* #ifdef WITH_EXPLICIT_DISSIPATION */
/* #ifdef _OPENMP */
/* 	#pragma omp parallel for private(i) schedule(static) */
/* #endif */
/* 	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) { */
/* 		dfldo.vx[i] += - nu * k2t[i] * fldi.vx[i]; */
/* 		dfldo.vy[i] += - nu * k2t[i] * fldi.vy[i]; */
/* 		dfldo.vz[i] += - nu * k2t[i] * fldi.vz[i]; */
		
/* #ifdef MHD */
/* 		dfldo.bx[i] += - eta * k2t[i] * fldi.bx[i]; */
/* 		dfldo.by[i] += - eta * k2t[i] * fldi.by[i]; */
/* 		dfldo.bz[i] += - eta * k2t[i] * fldi.bz[i]; */
/* #endif	// MHD */

/* #ifdef BOUSSINESQ */
/* 		dfldo.th[i] += - nu_th * k2t[i] * fldi.th[i]; */
/* #endif	// BOUSSINESQ */
/* 	} */

/* #endif	// WITH_EXPLICIT_DISSIPATION */
	
/************************************
** PRESSURE TERMS *******************
************************************/

#ifdef _OPENMP
	#pragma omp parallel for private(i,q0,q1) schedule(static)
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
			
#ifdef WITH_SHEAR
	  q0= S * ky[i] * fldi.vx[i] + kxt[i] * dfldo.vx[i] + ky[i] * dfldo.vy[i] + kzt[i] * dfldo.vz[i];
#ifdef WITH_ELLIPTICAL_VORTEX //AJB
	    q0 = (gamma+epsilon)*kxt[i]*fldi.vy[i]-(gamma-epsilon)*kyt[i]*fldi.vx[i] + kxt[i]*dfldo.vx[i] + kyt[i]*dfldo.vy[i] + kzt[i]*dfldo.vz[i];	  
#endif
#else
	  q0= kxt[i] * dfldo.vx[i] + kyt[i] * dfldo.vy[i] + kzt[i] * dfldo.vz[i];
#endif
/* po would contain the pressure field
		if(po != NULL) {
			po[i] = - I * ik2t[i] * q0;	// Save the pressure field (if needed)
		}
*/
		dfldo.vx[i] += -kxt[i]* q0 * ik2t[i];
		dfldo.vy[i] += -kyt[i]* q0 * ik2t[i];
		dfldo.vz[i] += -kzt[i]* q0 * ik2t[i];
	}

	return;
}
예제 #23
0
/*----------------------------------------------------------------------*
 |  make a triangulization of a polygon (private)             mwgee 10/05|
 *----------------------------------------------------------------------*/
bool MOERTEL::Overlap::Triangulation()
{
  // we have a polygon that is in clockwise order at this moment

  // if more than 3 points, find a center point
  int np = SizePointPolygon();
  if (np<3)
  {
	std::cout << "***ERR*** MOERTEL::Overlap::Triangulization:\n"
         << "***ERR*** # point in polygon < 3 ... very strange!!!\n"
         << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
    exit(EXIT_FAILURE);
  }
  if (np>3) // we have to add a center point
  {
    double xi[2];
	std::vector<Teuchos::RCP<MOERTEL::Point> > points; PointView(points);

#if 1 // compute center point xi as centroid
    Centroid(xi,points,np);    
    //std::cout << "Centroid xi : " << xi[0] << " / " << xi[1] << endl; fflush(stdout);
#endif
    
#if 0 // compute center point as nodal avergage
    xi[0] = xi[1] = 0.0;
    for (int i=0; i<np; ++i)
    {
      const double* pxi = points[i]->Xi();
      xi[0] += pxi[0];
      xi[1] += pxi[1];
    }
    xi[0] /= np;
    xi[1] /= np;
    //std::cout << "Nodal    xi : " << xi[0] << " / " << xi[1] << endl << endl; fflush(stdout);
#endif
    
    // create a point -1 as center point and add it to the polygon
    AddPointtoPolygon(-1,xi);
    points.clear();
  } // if (np>3)
  
  np = SizePointPolygon();
  std::vector<Teuchos::RCP<MOERTEL::Point> >  points; PointView(points);

  // create a MOERTEL::Node for every point
  int dof[3]; dof[0] = dof[1] = dof[2] = -1;
  
  // find real world coords for all points
  // find real world normal for all points
  // note that the polygon is in slave segment parameter space and is
  // completely contained in the slave segment. we can therefore use
  // slave segment values to interpolate polgon point values
  for (int i=0; i<np; ++i)
  {
    double x[3]; x[0] = x[1] = x[2] = 0.0;
    double n[3]; n[0] = n[1] = n[2] = 0.0;
    double val[20];
    sseg_.EvaluateFunction(0,points[i]->Xi(),val,sseg_.Nnode(),NULL);
    MOERTEL::Node** snodes = sseg_.Nodes();
    for (int j=0; j<sseg_.Nnode(); ++j)
      for (int k=0; k<3; ++k)
      {
        x[k] += val[j]*snodes[j]->X()[k];
        n[k] += val[j]*snodes[j]->N()[k];
      }
    const double length = MOERTEL::length(n,3);
    for (int j=0; j<3; ++j) n[j] /= length;
    // create a node with this coords and normal;
    MOERTEL::Node* node = new MOERTEL::Node(points[i]->Id(),x,3,dof,false,OutLevel());
    node->SetN(n);
    // set node in point
    points[i]->SetNode(node);
#if 0
	std::cout << *points[i];
#endif
  }  

  // find projection values for all points in polygon on mseg
  {
    double mxi[2];
	double gap;
    MOERTEL::Projector projector(inter_.IsOneDimensional(),OutLevel());
    for (int i=0; i<np; ++i)
    {
	  Teuchos::RCP<MOERTEL::Node> node = points[i]->Node();
      projector.ProjectNodetoSegment_NodalNormal(*node,mseg_,mxi,gap);
      // create a projected node and set it in node
      MOERTEL::ProjectedNode* pnode = new MOERTEL::ProjectedNode(*node,mxi,&mseg_);
      node->SetProjectedNode(pnode);
	  node->SetGap(gap);
#if 0
	  std::cout << "-------------------------------------------------------\n";
      if (mseg_.Nnode()==3)
      {
        if (mxi[0]<=1. && mxi[1]<=abs(1.-mxi[0]) && mxi[0]>=0. && mxi[1]>=0.)
          std::cout << "OVERLAP: point " << points[i]->Id() << " is in mseg, mxi " << mxi[0] << " / " << mxi[1] << endl;
        else
          std::cout << "OVERLAP: point " << points[i]->Id() << " is NOT in mseg, mxi " << mxi[0] << " / " << mxi[1] << endl;
      }
      else if (mseg_.Nnode()==4)
      {
        if (mxi[0]<=1.001 && mxi[0]>=-1.001 && mxi[1]<=1.001 && mxi[1]>=-1.001)
          std::cout << "OVERLAP: point " << points[i]->Id() << " is in mseg, mxi " << mxi[0] << " / " << mxi[1] << endl;
        else
          std::cout << "OVERLAP: point " << points[i]->Id() << " is NOT in mseg, mxi " << mxi[0] << " / " << mxi[1] << endl;
      }
      else
      {
		std::cout << "***ERR*** MOERTEL::Overlap::Triangulization:\n"
             << "***ERR*** # nodes " << mseg_.Nnode() << " of master segment is unknown\n"
             << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
        exit(EXIT_FAILURE);
      }
	  std::cout << "-------------------------------------------------------\n";
#endif

    }
  }

  // if we plan to interpolate function values at the gaussian points we need the
  // function values at the points
  if (exactvalues_==false)
  {
    // every point has 3 values of the 3 shape functions of the elements:
    // max 4 values from function 0 from sseg
    // max 4 values from function 1 from sseg
    // max 4 values from function 0 from mseg
    for (int i=0; i<np; ++i)
    {
      double val[20];
      int nmval = mseg_.Nnode();
      int nsval = sseg_.Nnode();
      // evaluate function 0 from sseg
      sseg_.EvaluateFunction(0,points[i]->Xi(),val,nsval,NULL);
      points[i]->StoreFunctionValues(0,val,nsval);
      // evaluate function 1 from sseg
      sseg_.EvaluateFunction(1,points[i]->Xi(),val,nsval,NULL);
      points[i]->StoreFunctionValues(1,val,nsval);
      // evaluate function 0 from mseg
      mseg_.EvaluateFunction(0,points[i]->Node()->GetProjectedNode()->Xi(),val,nmval,NULL);
      points[i]->StoreFunctionValues(2,val,nmval);
    }
  }
  
  // create the triangle elements from polygon with centerpoint
  // In case of np==3, there is no centerpoint
  if (np>3)
  {
    // the polygon is in clockwise order, center point is points[0] and has
    // id = -1
    if (points[0]->Id() != -1)
    {
	  std::cout << "***ERR*** MOERTEL::Overlap::Triangulization:\n"
           << "***ERR*** points[0]->Id() is not -1\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      exit(EXIT_FAILURE);
    }
    int nodeid[3];
    MOERTEL::Segment_BiLinearTri* tmp;
    MOERTEL::Function_LinearTri* func = new Function_LinearTri(OutLevel());
    for (int i=2; i<np; ++i)
    {
      // there are np-1 triangles
      // triangle ids go from 0 to np-2
      // a triangle is defined by nodes 0, i, i-1
      // *this class takes ownership of triangle
      nodeid[0]   = points[0]->Id();
      nodeid[1]   = points[i]->Id();
      nodeid[2]   = points[i-1]->Id();
      tmp = new MOERTEL::Segment_BiLinearTri(i-2,3,nodeid,OutLevel());
      // set a linear shape function to this triangle
      tmp->SetFunction(0,func);
      // add triangle to the *this class
      AddSegment(tmp->Id(),tmp);
    }
    // add the last triangle defined by nodes 0, 1, np-1 separately
    // *this class takes ownership of triangle
    nodeid[0]   = points[0]->Id();
    nodeid[1]   = points[1]->Id();
    nodeid[2]   = points[np-1]->Id();
    tmp = new MOERTEL::Segment_BiLinearTri(np-2,3,nodeid,OutLevel());
    // set a linear shape function to this triangle
    tmp->SetFunction(0,func);
    // add triangle to the *this class
    AddSegment(tmp->Id(),tmp);
    if (func) delete func; func = NULL;
  }
  else if (np==3) // single triangle without centerpoint
  {
    int nodeid[3];
    MOERTEL::Segment_BiLinearTri* tmp;
    MOERTEL::Function_LinearTri* func = new Function_LinearTri(OutLevel());
    nodeid[0] = points[0]->Id();
    nodeid[1] = points[2]->Id();
    nodeid[2] = points[1]->Id();
    // *this class takes ownership of triangle
    tmp = new MOERTEL::Segment_BiLinearTri(0,3,nodeid,OutLevel());
    // set a linear shape function to this triangle
    tmp->SetFunction(0,func);
    // add triangle the *this class
    AddSegment(tmp->Id(),tmp);
    if (func) delete func; func = NULL;
  }
  else
  {
	std::cout << "***ERR*** MOERTEL::Overlap::Triangulization:\n"
         << "***ERR*** # point in polygon < 3 ... very strange!!!\n"
         << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
    exit(EXIT_FAILURE);
  }
  
  // create ptr topology between triangle and nodes in points
  std::vector<MOERTEL::Node*> nodes(np);
  for (int i=0; i<np; ++i) nodes[i] = points[i]->Node().get();
  
  // loop segments and set ptr to nodes in them
  std::map<int,Teuchos::RCP<MOERTEL::Segment> >::iterator curr;
  for (curr=s_.begin(); curr != s_.end(); ++curr)
    curr->second->GetPtrstoNodes(nodes);
  
  nodes.clear();
  
  points.clear();
  
  return true;
}
예제 #24
0
파일: initflow.c 프로젝트: rmoleary/snoopy
/** Init the flow arrays... */	
void init_flow(struct Field fldi) {
	int i,n;
	int j,k;
	
	double dummy_var;
	
	DEBUG_START_FUNC;
	// Initialise vectors to 0
	
	for( n = 0 ; n < fldi.nfield ; n++) {
		for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
			fldi.farray[n][i] = 0.0;
		}
	}
	
#ifdef COMPRESSIBLE
	// Initialise the density to 1...
	if(rank==0) {
		fldi.d[0] = (double) NTOTAL;
	}
#endif
	if(param.init_large_scale_noise) init_LargeScaleNoise(fldi);
	
	if(param.init_large_scale_2D_noise) init_LargeScale2DNoise(fldi);

	if(param.init_vortex) init_KidaVortex(fldi);

	if(param.init_spatial_structure) init_SpatialStructure(fldi);

	if(param.init_white_noise) init_WhiteNoise(fldi);

	if(param.init_bench) init_Bench(fldi);

	if(param.init_mean_field) init_MeanField(fldi);
	
	if(param.init_dump) {
		read_dump(fldi, &dummy_var,"init.dmp");
		MPI_Printf("Initial conditions read successfully from the restart dump\n");
	}

#ifdef BOUNDARY_C
	boundary_c(fldi);
#endif
	
	projector(fldi.vx,fldi.vy,fldi.vz);

#ifdef MHD
	projector(fldi.bx,fldi.by,fldi.bz);
#endif

#ifdef WITH_PARTICLES
#ifdef WITH_ROTATION
		if(rank==0) {
			kappa_tau2 = 2.0*param.omega*(2.0*param.omega-param.shear) * param.particles_stime * param.particles_stime + (param.particles_dg_ratio + 1.0) * (param.particles_dg_ratio + 1.0);

	// This is a non trivial equilibrium for the particles+gas system
			fldi.vx[0] = param.particles_epsilon*param.particles_stime*param.particles_dg_ratio / kappa_tau2 * ( (double) NTOTAL);
			fldi.vy[0] = param.particles_epsilon*param.particles_dg_ratio*(1.0+param.particles_dg_ratio)/(2.0*param.omega*kappa_tau2) * ( (double) NTOTAL);
		}
#endif
#endif

#ifdef DEBUG
	MPI_Printf("Initflow:\n");
	D_show_all(fldi);
	MPI_Printf("**************************************************************************************\n");
#endif	
	
	DEBUG_END_FUNC;
	
	return;
}