<commit_before>#include <stdlib.h>

#include "PointContactDZ.h"
#include "iostream"
#include "Units.h"
using namespace GeFiCa;
using namespace std;
//for the case which point contact may not fall right on the grid, it will case
//a great different potential on space close to point contact the current
//design does not include when point contact is close to boundary of the whole
//detector.
PointContactDZ::PointContactDZ(int nd, int nz, const char *name,
      const char *title) : RhoZ(nd, nz, name, title),
   Height(5*cm),
   Radius(3*cm),
   PointContactH(0.01*cm),
   PointContactR(0.1*cm),
   HoleH(0),
   HoleR(0),
   HoleTaperW(0),
   HoleTaperH(0),
   TaperW(0.3*cm),
   TaperH(0.3*cm),
   CornerW(0.3*cm),
   CornerH(0.5*cm),
   WrapArroundR(2.5*cm),
   GrooveW(0.1*cm),
   GrooveH(0.1){};
//_____________________________________________________________________________
//
void PointContactDZ::SetBoundary()
{
   for(int i=0;i<fN;i++)
   {
      if(fC2[i]-PointContactH<fdC2m[i]&&fC2[i]>PointContactH&&fC1[i]<PointContactR&&fC1[i]>-PointContactR)
      {
         fdC2m[i]=fC2[i]-PointContactH;
      }
      if(fC1[i]-PointContactR<fdC1m[i]&&fC1[i]>0&&fC2[i]<PointContactH)
      {
         fdC1m[i]=fC1[i]-PointContactR;
      }
      if(-fC1[i]-PointContactR<fdC1p[i]&&fC1[i]<0&&fC2[i]<PointContactH)
      {
         fdC1p[i]=-fC1[i]-PointContactR;
      }
      if(WrapArroundR-fC1[i]<fdC1p[i]&&fC1[i]<WrapArroundR&&i<fN1)
      {
         fdC1p[i]=WrapArroundR-fC1[i];
      }
      if(WrapArroundR+fC1[i]<fdC1p[i]&&fC1[i]>-WrapArroundR&&i<fN1)
      {
         fdC1m[i]=WrapArroundR+fC1[i];
      }
   }
   double k=TaperH/(TaperW);
   double b=-(Radius-TaperW)*k;

   for(int i=0;i<fN;i++)
   {
      if(fC2[i]<=fC1[i]*k+b)
      {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
      if(fC2[i]<=-fC1[i]*k+b)
      {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
      if(fC2[i]-(fC1[i]*k+b)<fdC2p[i])
      {
         fdC2m[i]=fC2[i]-(k*fC1[i]+b);
         fdC1p[i]=fC1[i]-b/k-fC2[i]/k;
      }
      if(fC2[i]-(-k*fC1[i]+b)<fdC2m[i])
      {
         fdC2m[i]=fC2[i]-(-fC1[i]*k+b);
         fdC1m[i]=-fC1[i]/k-b/k-fC2[i];
      }
   }
   double x1=HoleTaperW,
          y1=Height,
          x2=HoleR,
          y2=Height-HoleTaperH,
          x3=Radius-CornerW,
          y3=Height,
          x4=Radius,
          y4=Height-CornerH;
   // y = k x + b
   double k1=(y1-y2)/(x1-x2);
   double b1=y1-k1*x1;
   double k2=(y3-y4)/(x3-x4);
   double b2=y3-k2*x3;

   for (int i=0;i<fN;i++) {
      if (x1!=x2)
      {
         //right side of hole taper
         if(fC1[i]-fC2[i]/k1+b1/k1<fdC1m[i] && fC2[i]>y2 &&
               fC1[i]-fC2[i]/k1+b1/k1>0)
            fdC1m[i]=fC1[i]-fC2[i]/k1+b1/k1;
         //left side of hole taper
         if(-fC1[i]-fC2[i]/k1+b1/k1>0&&-fC1[i]-fC2[i]/k1+b1/k1<fdC1p[i]&&fC2[i]>y2)
            fdC1p[i]=-fC1[i]-fC2[i]/k1+b1/k1;
      }
      else//x1==x2
      {
         //right side of hole taper
         if(fC1[i]-x1<fdC1m[i] && fC2[i]>y2 &&
               fC1[i]-x1>0)
            fdC1m[i]=fC1[i]-x1;
         //left side of hole taper
         if(-fC1[i]-x1>0&&-fC1[i]-x1<fdC1p[i]&&fC2[i]>y2)
            fdC1p[i]=-fC1[i]-x1;
      }
      //right side of hole taper
      if(fC1[i]-HoleR<fdC1m[i] && fC2[i]>HoleH &&
            fC1[i]-HoleR>0)
          fdC1m[i]=fC1[i]-HoleR;
      //left side of hole
      if(-fC1[i]-HoleR>0&&-fC1[i]-HoleR<fdC1p[i]&&fC2[i]>HoleH)
         fdC1p[i]=-fC1[i]-HoleR;
      //left corner
      if(fC1[i]+fC2[i]/k2-b2/k2>0 && fC1[i]+fC2[i]/k2-b2/k2<fdC1m[i] &&
            fC2[i]>y4) fdC1m[i]=fC1[i]+fC2[i]/k2-b2/k2;
      //right corner
      if(-fC1[i]+fC2[i]/k2-b2/k2>0&&-fC1[i]+fC2[i]/k2-b2/k2<fdC1p[i]&&fC2[i]>y4)
         fdC1p[i]=-fC1[i]+fC2[i]/k2-b2/k2;
      //down right side of hole
      if(-fC2[i]+fC1[i]*k1+b1>0&&-fC2[i]+fC1[i]*k1+b1<fdC2p[i]&&fC2[i]>y2)
         fdC2p[i]=-fC2[i]+fC1[i]*k1+b1;
      //down right of corner
      if(-fC2[i]-fC1[i]*k2+b2>0&&-fC2[i]-fC1[i]*k2+b2<fdC2p[i]&&fC2[i]>y4)
         fdC2p[i]=-fC2[i]-fC1[i]*k2+b2;
      //down left side of hole
      if(-fC2[i]-fC1[i]*k1+b1>0&&-fC2[i]-fC1[i]*k1+b1<fdC2p[i]&&fC2[i]>y2)
         fdC2p[i]=-fC2[i]-fC1[i]*k1+b1;
      //down left of corner
      if(-fC2[i]+fC1[i]*k2+b2>0&&-fC2[i]+fC1[i]*k2+b2<fdC2p[i]&&fC2[i]>y4)
         fdC2p[i]=-fC2[i]+fC1[i]*k2+b2;
      //down center of hole
      if(y2-fC2[i]<fdC2p[i]&&fC1[i]>-HoleR&&fC1[i]<HoleR)
         fdC2p[i]=y2-fC2[i];
   }
}
//_____________________________________________________________________________
//
void PointContactDZ::InitializeGrid()
{
   // we want no grid point right on z-axis
   if (fN1%2==1) Fatal("InitializeGrid", "Number of points in D can't be odd!");

   SetStepLength(2*Radius/(fN1-1),Height/(fN2-1));
   for(int i=fN;i-->0;) fC1[i]=fC1[i]-Radius;

   // set initial potential values
   for(int i=fN;i-->0;) {
      fV[i]=(V1+V0)/2;
      // set potential for inner electrodes
      if(fC1[i]>=-PointContactR && fC1[i]<=PointContactR
            && fC2[i]<=PointContactH) {
         fV[i]=V0;
         fIsFixed[i]=true;
      }
   }
   // set potential for outer electrodes
   for(int i=fN-1;i>=fN-fN1;i--) {
      fIsFixed[i]=true;
      fV[i]=V1;
   }
   for(int i=0;i<fN-fN1;i=i+fN1) {
      fIsFixed[i]=true;
      fIsFixed[i+fN1-1]=true;
      fV[i]=V1;
      fV[i+fN1-1]=V1;
   }
   for (int i=0;i<fN1;i++) {
      if(fC1[i]>=WrapArroundR||fC1[i]<=-WrapArroundR) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
   }

   double x1=HoleR+HoleTaperW,
          y1=Height,
          x2=HoleR,
          y2=Height-HoleTaperH,
          x3=Radius-CornerW,
          y3=Height,
          x4=Radius,
          y4=Height-CornerH;
   double k1=(y1-y2)/(x1-x2);
   double b1=y1-k1*x1;
   double k2=(y3-y4)/(x3-x4);
   double b2=(y3-k2*x3);
   if(x3!=x4)
      for(int i=0;i<fN;i++)
      {
         if(fC2[i]>-k2*(fC1[i])+b2||(fC2[i]>k2*(fC1[i])+b2))
         {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   if(x1!=x2)
   {
      for (int i=0;i<fN;i++) {
         if(((fC2[i]>-k1*(fC1[i])+b1
                     && fC2[i]>y2))&&fC1[i]<0) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
         if(((fC2[i]>k1*(fC1[i])+b1
                     && fC2[i]>y2))&&fC1[i]>0) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   }
   else//x1==x2
   {
      for (int i=0;i<fN;i++)
      {
         if(fC1[i]<=x1&&fC1[i]>=-x1&&fC2[i]>=y2)
         {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }

   }
   for (int i=0;i<fN;i++)
   {
      if(fC1[i]<=HoleR&&fC1[i]>=-HoleR&&fC2[i]>=Height-HoleH)
      {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
   }
   SetBoundary();
}
//_____________________________________________________________________________
//
#include <fstream>
bool PointContactDZ::SaveFieldAsFieldgen(const char * fout)
{
   ofstream outfile(fout);

   outfile<<"# height "<< Height;
   outfile<<"\n# xtal_radius "<<Radius;
   outfile<<"\n# pc_length   "<<PointContactH;
   outfile<<"\n# pc_radius   "<<PointContactR;
   outfile<<"\n# wrap_around_radius "<<WrapArroundR;
   outfile<<"\n# grid size on r "<<fdC1p[0];
   outfile<<"\n# grid size on z "<<fdC2p[0];
   outfile<<"\n# impurity_z0  "<<fImpurity[0];
   outfile<<"\n# xtal_HV      "<<V0;
   outfile<<"\n# max_iterations "<<MaxIterations;
   outfile<<"\n# ";
   outfile<<"\n## r (mm), z (mm), V (V),  E (V/cm), E_r (V/cm), E_z (V/cm)";
   for (int i=0;i<fN;i++) {
      double E=sqrt(fE1[i]*fE1[i]+fE2[i]*fE2[i]);
      outfile<<"\n"<<fC1[i]<<"  "<<fC2[i]<<"  "<<fV[i]<<"  "<<E<<"  "<<fE1[i]<<"  "<<fE2[i];
   }
   outfile.close();
   return true;
}
void PointContactDZ::SetGridImpurity()
{

   X::SetGridImpurity();

   if(TaperW+WrapArroundR<Radius)
   {
      for(int i=0;i<fN;i++)
      {
         if((fC1[i]>WrapArroundR-GrooveW && fC1[i]<WrapArroundR && fC2[i]<GrooveH)||
            (fC1[i]<-(WrapArroundR-GrooveW) && fC1[i]>-(WrapArroundR) && fC2[i]<GrooveH))
         {
            fImpurity[i]=0;
            fV[i]=0;
         }
      }
   }
}
<commit_msg>adde protection for groove setup<commit_after>#include <stdlib.h>

#include "PointContactDZ.h"
#include "iostream"
#include "Units.h"
using namespace GeFiCa;
using namespace std;
//for the case which point contact may not fall right on the grid, it will case
//a great different potential on space close to point contact the current
//design does not include when point contact is close to boundary of the whole
//detector.
PointContactDZ::PointContactDZ(int nd, int nz, const char *name,
      const char *title) : RhoZ(nd, nz, name, title),
   Height(5*cm),
   Radius(3*cm),
   PointContactH(0),
   PointContactR(1*mm),
   HoleH(0),
   HoleR(0),
   HoleTaperW(0),
   HoleTaperH(0),
   TaperW(1*mm),
   TaperH(1*mm),
   CornerW(1*mm),
   CornerH(1*mm),
   GrooveW(0),
   GrooveH(0) { WrapArroundR=Radius; }
//_____________________________________________________________________________
//
void PointContactDZ::SetBoundary()
{
   for(int i=0;i<fN;i++)
   {
      if(fC2[i]-PointContactH<fdC2m[i]&&fC2[i]>PointContactH&&fC1[i]<PointContactR&&fC1[i]>-PointContactR)
      {
         fdC2m[i]=fC2[i]-PointContactH;
      }
      if(fC1[i]-PointContactR<fdC1m[i]&&fC1[i]>0&&fC2[i]<PointContactH)
      {
         fdC1m[i]=fC1[i]-PointContactR;
      }
      if(-fC1[i]-PointContactR<fdC1p[i]&&fC1[i]<0&&fC2[i]<PointContactH)
      {
         fdC1p[i]=-fC1[i]-PointContactR;
      }
      if(WrapArroundR-fC1[i]<fdC1p[i]&&fC1[i]<WrapArroundR&&i<fN1)
      {
         fdC1p[i]=WrapArroundR-fC1[i];
      }
      if(WrapArroundR+fC1[i]<fdC1p[i]&&fC1[i]>-WrapArroundR&&i<fN1)
      {
         fdC1m[i]=WrapArroundR+fC1[i];
      }
   }
   double k=TaperH/(TaperW);
   double b=-(Radius-TaperW)*k;

   for(int i=0;i<fN;i++)
   {
      if(fC2[i]<=fC1[i]*k+b)
      {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
      if(fC2[i]<=-fC1[i]*k+b)
      {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
      if(fC2[i]-(fC1[i]*k+b)<fdC2p[i])
      {
         fdC2m[i]=fC2[i]-(k*fC1[i]+b);
         fdC1p[i]=fC1[i]-b/k-fC2[i]/k;
      }
      if(fC2[i]-(-k*fC1[i]+b)<fdC2m[i])
      {
         fdC2m[i]=fC2[i]-(-fC1[i]*k+b);
         fdC1m[i]=-fC1[i]/k-b/k-fC2[i];
      }
   }
   double x1=HoleTaperW,
          y1=Height,
          x2=HoleR,
          y2=Height-HoleTaperH,
          x3=Radius-CornerW,
          y3=Height,
          x4=Radius,
          y4=Height-CornerH;
   // y = k x + b
   double k1=(y1-y2)/(x1-x2);
   double b1=y1-k1*x1;
   double k2=(y3-y4)/(x3-x4);
   double b2=y3-k2*x3;

   for (int i=0;i<fN;i++) {
      if (x1!=x2)
      {
         //right side of hole taper
         if(fC1[i]-fC2[i]/k1+b1/k1<fdC1m[i] && fC2[i]>y2 &&
               fC1[i]-fC2[i]/k1+b1/k1>0)
            fdC1m[i]=fC1[i]-fC2[i]/k1+b1/k1;
         //left side of hole taper
         if(-fC1[i]-fC2[i]/k1+b1/k1>0&&-fC1[i]-fC2[i]/k1+b1/k1<fdC1p[i]&&fC2[i]>y2)
            fdC1p[i]=-fC1[i]-fC2[i]/k1+b1/k1;
      }
      else//x1==x2
      {
         //right side of hole taper
         if(fC1[i]-x1<fdC1m[i] && fC2[i]>y2 &&
               fC1[i]-x1>0)
            fdC1m[i]=fC1[i]-x1;
         //left side of hole taper
         if(-fC1[i]-x1>0&&-fC1[i]-x1<fdC1p[i]&&fC2[i]>y2)
            fdC1p[i]=-fC1[i]-x1;
      }
      //right side of hole taper
      if(fC1[i]-HoleR<fdC1m[i] && fC2[i]>HoleH &&
            fC1[i]-HoleR>0)
          fdC1m[i]=fC1[i]-HoleR;
      //left side of hole
      if(-fC1[i]-HoleR>0&&-fC1[i]-HoleR<fdC1p[i]&&fC2[i]>HoleH)
         fdC1p[i]=-fC1[i]-HoleR;
      //left corner
      if(fC1[i]+fC2[i]/k2-b2/k2>0 && fC1[i]+fC2[i]/k2-b2/k2<fdC1m[i] &&
            fC2[i]>y4) fdC1m[i]=fC1[i]+fC2[i]/k2-b2/k2;
      //right corner
      if(-fC1[i]+fC2[i]/k2-b2/k2>0&&-fC1[i]+fC2[i]/k2-b2/k2<fdC1p[i]&&fC2[i]>y4)
         fdC1p[i]=-fC1[i]+fC2[i]/k2-b2/k2;
      //down right side of hole
      if(-fC2[i]+fC1[i]*k1+b1>0&&-fC2[i]+fC1[i]*k1+b1<fdC2p[i]&&fC2[i]>y2)
         fdC2p[i]=-fC2[i]+fC1[i]*k1+b1;
      //down right of corner
      if(-fC2[i]-fC1[i]*k2+b2>0&&-fC2[i]-fC1[i]*k2+b2<fdC2p[i]&&fC2[i]>y4)
         fdC2p[i]=-fC2[i]-fC1[i]*k2+b2;
      //down left side of hole
      if(-fC2[i]-fC1[i]*k1+b1>0&&-fC2[i]-fC1[i]*k1+b1<fdC2p[i]&&fC2[i]>y2)
         fdC2p[i]=-fC2[i]-fC1[i]*k1+b1;
      //down left of corner
      if(-fC2[i]+fC1[i]*k2+b2>0&&-fC2[i]+fC1[i]*k2+b2<fdC2p[i]&&fC2[i]>y4)
         fdC2p[i]=-fC2[i]+fC1[i]*k2+b2;
      //down center of hole
      if(y2-fC2[i]<fdC2p[i]&&fC1[i]>-HoleR&&fC1[i]<HoleR)
         fdC2p[i]=y2-fC2[i];
   }
}
//_____________________________________________________________________________
//
void PointContactDZ::InitializeGrid()
{
   // we want no grid point right on z-axis
   if (fN1%2==1) Fatal("InitializeGrid", "Number of points in D can't be odd!");

   SetStepLength(2*Radius/(fN1-1),Height/(fN2-1));
   for(int i=fN;i-->0;) fC1[i]=fC1[i]-Radius;

   // set initial potential values
   for(int i=fN;i-->0;) {
      fV[i]=(V1+V0)/2;
      // set potential for inner electrodes
      if(fC1[i]>=-PointContactR && fC1[i]<=PointContactR
            && fC2[i]<=PointContactH) {
         fV[i]=V0;
         fIsFixed[i]=true;
      }
   }
   // set potential for outer electrodes
   for(int i=fN-1;i>=fN-fN1;i--) {
      fIsFixed[i]=true;
      fV[i]=V1;
   }
   for(int i=0;i<fN-fN1;i=i+fN1) {
      fIsFixed[i]=true;
      fIsFixed[i+fN1-1]=true;
      fV[i]=V1;
      fV[i+fN1-1]=V1;
   }
   for (int i=0;i<fN1;i++) {
      if(fC1[i]>=WrapArroundR||fC1[i]<=-WrapArroundR) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
   }

   double x1=HoleR+HoleTaperW,
          y1=Height,
          x2=HoleR,
          y2=Height-HoleTaperH,
          x3=Radius-CornerW,
          y3=Height,
          x4=Radius,
          y4=Height-CornerH;
   double k1=(y1-y2)/(x1-x2);
   double b1=y1-k1*x1;
   double k2=(y3-y4)/(x3-x4);
   double b2=(y3-k2*x3);
   if(x3!=x4)
      for(int i=0;i<fN;i++)
      {
         if(fC2[i]>-k2*(fC1[i])+b2||(fC2[i]>k2*(fC1[i])+b2))
         {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   if(x1!=x2)
   {
      for (int i=0;i<fN;i++) {
         if(((fC2[i]>-k1*(fC1[i])+b1
                     && fC2[i]>y2))&&fC1[i]<0) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
         if(((fC2[i]>k1*(fC1[i])+b1
                     && fC2[i]>y2))&&fC1[i]>0) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   }
   else//x1==x2
   {
      for (int i=0;i<fN;i++)
      {
         if(fC1[i]<=x1&&fC1[i]>=-x1&&fC2[i]>=y2)
         {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }

   }
   for (int i=0;i<fN;i++)
   {
      if(fC1[i]<=HoleR&&fC1[i]>=-HoleR&&fC2[i]>=Height-HoleH)
      {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
   }
   SetBoundary();
}
//_____________________________________________________________________________
//
#include <fstream>
bool PointContactDZ::SaveFieldAsFieldgen(const char * fout)
{
   ofstream outfile(fout);

   outfile<<"# height "<< Height;
   outfile<<"\n# xtal_radius "<<Radius;
   outfile<<"\n# pc_length   "<<PointContactH;
   outfile<<"\n# pc_radius   "<<PointContactR;
   outfile<<"\n# wrap_around_radius "<<WrapArroundR;
   outfile<<"\n# grid size on r "<<fdC1p[0];
   outfile<<"\n# grid size on z "<<fdC2p[0];
   outfile<<"\n# impurity_z0  "<<fImpurity[0];
   outfile<<"\n# xtal_HV      "<<V0;
   outfile<<"\n# max_iterations "<<MaxIterations;
   outfile<<"\n# ";
   outfile<<"\n## r (mm), z (mm), V (V),  E (V/cm), E_r (V/cm), E_z (V/cm)";
   for (int i=0;i<fN;i++) {
      double E=sqrt(fE1[i]*fE1[i]+fE2[i]*fE2[i]);
      outfile<<"\n"<<fC1[i]<<"  "<<fC2[i]<<"  "<<fV[i]<<"  "<<E<<"  "<<fE1[i]<<"  "<<fE2[i];
   }
   outfile.close();
   return true;
}
//_____________________________________________________________________________
//
void PointContactDZ::SetGridImpurity()
{
   X::SetGridImpurity();

   if (TaperW+WrapArroundR<Radius || WrapArroundR-GrooveW>PointContactR) {
      for (int i=0;i<fN;i++) {
         if((fC1[i]>WrapArroundR-GrooveW
                  && fC1[i]<WrapArroundR && fC2[i]<GrooveH)
               || (fC1[i]<-(WrapArroundR-GrooveW)
                  && fC1[i]>-(WrapArroundR) && fC2[i]<GrooveH)) {
            fImpurity[i]=0;
            fV[i]=0;
         }
      }
   } else {
      Error("SetGridImpurity",
            "Groove and/or Wrap around setup are/is wrong. Abort!");
      abort();
   }
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#if     qPlatform_Windows
#include    <windows.h>
#include    <shellapi.h>
#include    <shlobj.h>
#elif   qPlatform_POSIX
#include    <unistd.h>
#endif

#if     qPlatform_Windows
#include    "../../Execution/Platform/Windows/Exception.h"
#include    "../../Execution/Platform/Windows/HRESULTErrorException.h"
#endif
#include    "../../Execution/ErrNoException.h"

#include    "../../IO/FileAccessException.h"
#include    "../../IO/FileBusyException.h"
#include    "../../IO/FileFormatException.h"
#include    "../../Memory/SmallStackBuffer.h"

#include    "FileUtils.h"

#include    "FileSystem.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::FileSystem;

#if     qPlatform_Windows
using   Execution::Platform::Windows::ThrowIfFalseGetLastError;
#endif

IO::FileSystem::FileSystem  IO::FileSystem::FileSystem::Default ()
{
    static  IO::FileSystem::FileSystem  sThe_;
    return sThe_;
}

bool    IO::FileSystem::FileSystem::Access (const String& fileFullPath, FileAccessMode accessMode) const
{
    // quick hack - not fully implemented - but since advsiory only - not too important...
#if     qPlatform_Windows
    if ((accessMode & FileAccessMode::eRead) == FileAccessMode::eNoAccess) {
        DWORD attribs = ::GetFileAttributesW (fileFullPath.c_str ());
        if (attribs == INVALID_FILE_ATTRIBUTES) {
            return false;
        }
    }
    if ((accessMode & FileAccessMode::eWrite) == FileAccessMode::eNoAccess) {
        DWORD attribs = ::GetFileAttributesW (fileFullPath.c_str ());
        if ((attribs == INVALID_FILE_ATTRIBUTES) or (attribs & FILE_ATTRIBUTE_READONLY)) {
            return false;
        }
    }
    return true;
#elif   qPlatform_POSIX
    // Not REALLY right - but an OK hack for now... -- LGP 2011-09-26
    //http://linux.die.net/man/2/access
    if ((accessMode & FileAccessMode::eRead) == FileAccessMode::eNoAccess) {
        if (access (fileFullPath.AsSDKString().c_str (), R_OK) != 0) {
            return false;
        }
    }
    if ((accessMode & FileAccessMode::eWrite) == FileAccessMode::eNoAccess) {
        if (access (fileFullPath.AsSDKString().c_str (), W_OK) != 0) {
            return false;
        }
    }
    return true;
#else
    AssertNotImplemented ();
    return false;
#endif
}

void    IO::FileSystem::FileSystem::CheckAccess (const String& fileFullPath, FileAccessMode accessMode)
{
    // quick hack - not fully implemented - but since advsiory only - not too important...

    if (not Access (fileFullPath, accessMode)) {
        // FOR NOW - MIMIC OLD CODE - BUT FIX TO CHECK READ AND WRITE (AND BOTH) ACCESS DEPENDING ON ARGS) -- LGP 2009-08-15
        Execution::DoThrow (FileAccessException (fileFullPath, accessMode));
    }
}

void    IO::FileSystem::FileSystem::CheckFileAccess (const String& fileFullPath, bool checkCanRead, bool checkCanWrite)
{
    if (checkCanRead and checkCanWrite) {
        CheckAccess (fileFullPath, IO::FileAccessMode::eReadWrite);
    }
    else if (checkCanRead) {
        CheckAccess (fileFullPath, IO::FileAccessMode::eRead);
    }
    else if (checkCanWrite) {
        CheckAccess (fileFullPath, IO::FileAccessMode::eWrite);
    }
}

/*
 ********************************************************************************
 ************************* FileSystem::ResolveShortcut **************************
 ********************************************************************************
 */
String IO::FileSystem::FileSystem::ResolveShortcut (const String& path2FileOrShortcut)
{
#if     qPlatform_Windows
    // NB: this requires COM, and for now - I don't want the support module depending on the COM module,
    // so just allow this to fail if COM isn't initialized.
    //      -- LGP 2007-09-23
    //
    {
        SHFILEINFO   info;
        memset (&info, 0, sizeof (info));
        if (::SHGetFileInfo (path2FileOrShortcut.AsSDKString ().c_str (), 0, &info, sizeof (info), SHGFI_ATTRIBUTES) == 0)
        {
            return path2FileOrShortcut;
        }
        // not a shortcut?
        if (!(info.dwAttributes & SFGAO_LINK))
        {
            return path2FileOrShortcut;
        }
    }

    // obtain the IShellLink interface
    IShellLink*     psl =   nullptr;
    IPersistFile*   ppf =   nullptr;
    try {
        if (FAILED (::CoCreateInstance (CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl))) {
            return path2FileOrShortcut;
        }
        if (SUCCEEDED (psl->QueryInterface (IID_IPersistFile, (LPVOID*)&ppf))) {
            if (SUCCEEDED (ppf->Load (path2FileOrShortcut.c_str (), STGM_READ))) {
                // Resolve the link, this may post UI to find the link
                if (SUCCEEDED (psl->Resolve(0, SLR_NO_UI))) {
                    TCHAR   path[MAX_PATH + 1];
                    memset (path, 0, sizeof (path));
                    if (SUCCEEDED (psl->GetPath (path, NEltsOf (path), nullptr, 0))) {
                        ppf->Release ();
                        ppf = nullptr;
                        psl->Release ();
                        psl = nullptr;
                        return String::FromSDKString (path);
                    }
                }
            }
        }
    }
    catch (...) {
        if (ppf != nullptr) {
            ppf->Release ();
        }
        if (psl != nullptr) {
            psl->Release ();
        }
        Execution::DoReThrow ();
    }
    if (ppf != nullptr) {
        ppf->Release ();
    }
    if (psl != nullptr) {
        psl->Release ();
    }
    return path2FileOrShortcut;
#else
    Memory::SmallStackBuffer<Characters::SDKChar> buf (1024);
    ssize_t n;
    while ( (n = readlink (path2FileOrShortcut.AsSDKString ().c_str (), buf, buf.GetSize ())) == buf.GetSize ()) {
        buf.GrowToSize (buf.GetSize () * 2);
    }
    if (n < 0) {
        Execution::errno_ErrorException::DoThrow (errno);
    }
    Assert (n <= buf.GetSize ());   // could leave no room for NUL-byte, but not needed
    return String::FromSDKString (SDKString (buf.begin (), buf.begin () + n));
#endif
}

/*
 ********************************************************************************
 *************************** FileSystem::GetFileSize ****************************
 ********************************************************************************
 */
FileOffset_t    IO::FileSystem::FileSystem::GetFileSize (const String& fileName)
{
#if     qPlatform_Windows
    WIN32_FILE_ATTRIBUTE_DATA   fileAttrData;
    (void)::memset (&fileAttrData, 0, sizeof (fileAttrData));
    Execution::Platform::Windows::ThrowIfFalseGetLastError (::GetFileAttributesExW (fileName.c_str (), GetFileExInfoStandard, &fileAttrData));
    return fileAttrData.nFileSizeLow + (static_cast<FileOffset_t> (fileAttrData.nFileSizeHigh) << 32);
#else
    AssertNotImplemented ();
    return 0;
#endif
}

/*
 ********************************************************************************
 ********************* FileSystem::GetFileLastModificationDate ******************
 ********************************************************************************
 */
DateTime        IO::FileSystem::FileSystem::GetFileLastModificationDate (const String& fileName)
{
#if     qPlatform_Windows
    WIN32_FILE_ATTRIBUTE_DATA   fileAttrData;
    (void)::memset (&fileAttrData, 0, sizeof (fileAttrData));
    ThrowIfFalseGetLastError (::GetFileAttributesExW (fileName.c_str (), GetFileExInfoStandard, &fileAttrData));
    return DateTime (fileAttrData.ftLastWriteTime);
#else
    AssertNotImplemented ();
    return DateTime ();
#endif
}

/*
 ********************************************************************************
 *********************** FileSystem::GetFileLastAccessDate **********************
 ********************************************************************************
 */
DateTime    IO::FileSystem::FileSystem::GetFileLastAccessDate (const String& fileName)
{
#if     qPlatform_Windows
    WIN32_FILE_ATTRIBUTE_DATA   fileAttrData;
    (void)::memset (&fileAttrData, 0, sizeof (fileAttrData));
    ThrowIfFalseGetLastError (::GetFileAttributesExW (fileName.c_str (), GetFileExInfoStandard, &fileAttrData));
    return DateTime (fileAttrData.ftLastAccessTime);
#else
    AssertNotImplemented ();
    return DateTime ();
#endif
}

<commit_msg>fixed serious bug (backwards test) on IO::FileSystem::FileSystem::Access<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#if     qPlatform_Windows
#include    <windows.h>
#include    <shellapi.h>
#include    <shlobj.h>
#elif   qPlatform_POSIX
#include    <unistd.h>
#endif

#if     qPlatform_Windows
#include    "../../Execution/Platform/Windows/Exception.h"
#include    "../../Execution/Platform/Windows/HRESULTErrorException.h"
#endif
#include    "../../Execution/ErrNoException.h"

#include    "../../IO/FileAccessException.h"
#include    "../../IO/FileBusyException.h"
#include    "../../IO/FileFormatException.h"
#include    "../../Memory/SmallStackBuffer.h"

#include    "FileUtils.h"

#include    "FileSystem.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::FileSystem;

#if     qPlatform_Windows
using   Execution::Platform::Windows::ThrowIfFalseGetLastError;
#endif

IO::FileSystem::FileSystem  IO::FileSystem::FileSystem::Default ()
{
    static  IO::FileSystem::FileSystem  sThe_;
    return sThe_;
}

bool    IO::FileSystem::FileSystem::Access (const String& fileFullPath, FileAccessMode accessMode) const
{
    // quick hack - not fully implemented - but since advsiory only - not too important...
#if     qPlatform_Windows
    if ((accessMode & FileAccessMode::eRead) == FileAccessMode::eRead) {
        DWORD attribs = ::GetFileAttributesW (fileFullPath.c_str ());
        if (attribs == INVALID_FILE_ATTRIBUTES) {
            return false;
        }
    }
    if ((accessMode & FileAccessMode::eWrite) == FileAccessMode::eWrite) {
        DWORD attribs = ::GetFileAttributesW (fileFullPath.c_str ());
        if ((attribs == INVALID_FILE_ATTRIBUTES) or (attribs & FILE_ATTRIBUTE_READONLY)) {
            return false;
        }
    }
    return true;
#elif   qPlatform_POSIX
    // Not REALLY right - but an OK hack for now... -- LGP 2011-09-26
    //http://linux.die.net/man/2/access
    if ((accessMode & FileAccessMode::eRead) == FileAccessMode::eNoAccess) {
        if (access (fileFullPath.AsSDKString().c_str (), R_OK) != 0) {
            return false;
        }
    }
    if ((accessMode & FileAccessMode::eWrite) == FileAccessMode::eNoAccess) {
        if (access (fileFullPath.AsSDKString().c_str (), W_OK) != 0) {
            return false;
        }
    }
    return true;
#else
    AssertNotImplemented ();
    return false;
#endif
}

void    IO::FileSystem::FileSystem::CheckAccess (const String& fileFullPath, FileAccessMode accessMode)
{
    // quick hack - not fully implemented - but since advsiory only - not too important...

    if (not Access (fileFullPath, accessMode)) {
        // FOR NOW - MIMIC OLD CODE - BUT FIX TO CHECK READ AND WRITE (AND BOTH) ACCESS DEPENDING ON ARGS) -- LGP 2009-08-15
        Execution::DoThrow (FileAccessException (fileFullPath, accessMode));
    }
}

void    IO::FileSystem::FileSystem::CheckFileAccess (const String& fileFullPath, bool checkCanRead, bool checkCanWrite)
{
    if (checkCanRead and checkCanWrite) {
        CheckAccess (fileFullPath, IO::FileAccessMode::eReadWrite);
    }
    else if (checkCanRead) {
        CheckAccess (fileFullPath, IO::FileAccessMode::eRead);
    }
    else if (checkCanWrite) {
        CheckAccess (fileFullPath, IO::FileAccessMode::eWrite);
    }
}

/*
 ********************************************************************************
 ************************* FileSystem::ResolveShortcut **************************
 ********************************************************************************
 */
String IO::FileSystem::FileSystem::ResolveShortcut (const String& path2FileOrShortcut)
{
#if     qPlatform_Windows
    // NB: this requires COM, and for now - I don't want the support module depending on the COM module,
    // so just allow this to fail if COM isn't initialized.
    //      -- LGP 2007-09-23
    //
    {
        SHFILEINFO   info;
        memset (&info, 0, sizeof (info));
        if (::SHGetFileInfo (path2FileOrShortcut.AsSDKString ().c_str (), 0, &info, sizeof (info), SHGFI_ATTRIBUTES) == 0)
        {
            return path2FileOrShortcut;
        }
        // not a shortcut?
        if (!(info.dwAttributes & SFGAO_LINK))
        {
            return path2FileOrShortcut;
        }
    }

    // obtain the IShellLink interface
    IShellLink*     psl =   nullptr;
    IPersistFile*   ppf =   nullptr;
    try {
        if (FAILED (::CoCreateInstance (CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl))) {
            return path2FileOrShortcut;
        }
        if (SUCCEEDED (psl->QueryInterface (IID_IPersistFile, (LPVOID*)&ppf))) {
            if (SUCCEEDED (ppf->Load (path2FileOrShortcut.c_str (), STGM_READ))) {
                // Resolve the link, this may post UI to find the link
                if (SUCCEEDED (psl->Resolve(0, SLR_NO_UI))) {
                    TCHAR   path[MAX_PATH + 1];
                    memset (path, 0, sizeof (path));
                    if (SUCCEEDED (psl->GetPath (path, NEltsOf (path), nullptr, 0))) {
                        ppf->Release ();
                        ppf = nullptr;
                        psl->Release ();
                        psl = nullptr;
                        return String::FromSDKString (path);
                    }
                }
            }
        }
    }
    catch (...) {
        if (ppf != nullptr) {
            ppf->Release ();
        }
        if (psl != nullptr) {
            psl->Release ();
        }
        Execution::DoReThrow ();
    }
    if (ppf != nullptr) {
        ppf->Release ();
    }
    if (psl != nullptr) {
        psl->Release ();
    }
    return path2FileOrShortcut;
#else
    Memory::SmallStackBuffer<Characters::SDKChar> buf (1024);
    ssize_t n;
    while ( (n = readlink (path2FileOrShortcut.AsSDKString ().c_str (), buf, buf.GetSize ())) == buf.GetSize ()) {
        buf.GrowToSize (buf.GetSize () * 2);
    }
    if (n < 0) {
        Execution::errno_ErrorException::DoThrow (errno);
    }
    Assert (n <= buf.GetSize ());   // could leave no room for NUL-byte, but not needed
    return String::FromSDKString (SDKString (buf.begin (), buf.begin () + n));
#endif
}

/*
 ********************************************************************************
 *************************** FileSystem::GetFileSize ****************************
 ********************************************************************************
 */
FileOffset_t    IO::FileSystem::FileSystem::GetFileSize (const String& fileName)
{
#if     qPlatform_Windows
    WIN32_FILE_ATTRIBUTE_DATA   fileAttrData;
    (void)::memset (&fileAttrData, 0, sizeof (fileAttrData));
    Execution::Platform::Windows::ThrowIfFalseGetLastError (::GetFileAttributesExW (fileName.c_str (), GetFileExInfoStandard, &fileAttrData));
    return fileAttrData.nFileSizeLow + (static_cast<FileOffset_t> (fileAttrData.nFileSizeHigh) << 32);
#else
    AssertNotImplemented ();
    return 0;
#endif
}

/*
 ********************************************************************************
 ********************* FileSystem::GetFileLastModificationDate ******************
 ********************************************************************************
 */
DateTime        IO::FileSystem::FileSystem::GetFileLastModificationDate (const String& fileName)
{
#if     qPlatform_Windows
    WIN32_FILE_ATTRIBUTE_DATA   fileAttrData;
    (void)::memset (&fileAttrData, 0, sizeof (fileAttrData));
    ThrowIfFalseGetLastError (::GetFileAttributesExW (fileName.c_str (), GetFileExInfoStandard, &fileAttrData));
    return DateTime (fileAttrData.ftLastWriteTime);
#else
    AssertNotImplemented ();
    return DateTime ();
#endif
}

/*
 ********************************************************************************
 *********************** FileSystem::GetFileLastAccessDate **********************
 ********************************************************************************
 */
DateTime    IO::FileSystem::FileSystem::GetFileLastAccessDate (const String& fileName)
{
#if     qPlatform_Windows
    WIN32_FILE_ATTRIBUTE_DATA   fileAttrData;
    (void)::memset (&fileAttrData, 0, sizeof (fileAttrData));
    ThrowIfFalseGetLastError (::GetFileAttributesExW (fileName.c_str (), GetFileExInfoStandard, &fileAttrData));
    return DateTime (fileAttrData.ftLastAccessTime);
#else
    AssertNotImplemented ();
    return DateTime ();
#endif
}

<|endoftext|>


<commit_before>/********************************************************************
 * Copyright © 2018 Computational Molecular Biology Group,          *
 *                  Freie Universität Berlin (GER)                  *
 *                                                                  *
 * Redistribution and use in source and binary forms, with or       *
 * without modification, are permitted provided that the            *
 * following conditions are met:                                    *
 *  1. Redistributions of source code must retain the above         *
 *     copyright notice, this list of conditions and the            *
 *     following disclaimer.                                        *
 *  2. Redistributions in binary form must reproduce the above      *
 *     copyright notice, this list of conditions and the following  *
 *     disclaimer in the documentation and/or other materials       *
 *     provided with the distribution.                              *
 *  3. Neither the name of the copyright holder nor the names of    *
 *     its contributors may be used to endorse or promote products  *
 *     derived from this software without specific                  *
 *     prior written permission.                                    *
 *                                                                  *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND           *
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,      *
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF         *
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE         *
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR            *
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     *
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,         *
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,      *
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)    *
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF      *
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                       *
 ********************************************************************/

/**
 * @file Potentials.cpp
 * @brief Core library implementation of order 1 potentials
 * @author clonker
 * @author chrisfroe
 * @date 20.06.16
 */

#include <readdy/model/Kernel.h>
#include <readdy/model/potentials/PotentialsOrder1.h>

namespace readdy {
namespace model {
namespace potentials {

std::string PotentialRegistry::describe() const {
    namespace rus = readdy::util::str;
    auto find_pot_name = [this](ParticleTypeId type) -> const std::string {
        for (auto &&t : _types.get().typeMapping()) {
            if (t.second == type) return t.first;
        }
        return "";
    };
    std::string description;
    if (!potentialsOrder1().empty()) {
        description += fmt::format(" - potentials of order 1:{}", rus::newline);
        for (const auto &types : potentialsOrder1()) {
            description += fmt::format("     * for type \"{}\"{}", find_pot_name(types.first), rus::newline);
            for (auto pot : types.second) {
                description += fmt::format("         * {}{}", pot->describe(), rus::newline);
            }
        }
    }
    if (!potentialsOrder2().empty()) {
        description += fmt::format(" - potentials of order 2:{}", rus::newline);
        for (const auto &types : potentialsOrder2()) {
            description += fmt::format(R"(     * for types "{}" and "{}"{})", find_pot_name(std::get<0>(types.first)),
                                       find_pot_name(std::get<1>(types.first)), rus::newline);
            for (auto pot : types.second) {
                description += fmt::format("         * {}{}", pot->describe(), rus::newline);
            }
        }
    }
    return description;
}

/////////////////////////////////////////////////////////////////////////////
//
// Potentials order 1
//
/////////////////////////////////////////////////////////////////////////////

/**
 * Box potential
 */

Vec3 getMinExtent(const Vec3 &origin, const Vec3 &extent) {
    Vec3 result{0, 0, 0};
    for (auto i = 0; i < 3; i++) {
        if (extent[i] > 0) {
            result[i] = origin[i];
        } else {
            result[i] = origin[i] + extent[i];
        }
    }
    return result;
}

Vec3 getMaxExtent(const Vec3 &origin, const Vec3 &extent) {
    Vec3 result{0, 0, 0};
    for (auto i = 0; i < 3; i++) {
        if (extent[i] > 0) {
            result[i] = origin[i] + extent[i];
        } else {
            result[i] = origin[i];
        }
    }
    return result;
}

Box::Box(particle_type_type particleType, scalar forceConstant, const Vec3 &origin,
                             const Vec3 &extent)
        : super(particleType), origin(origin), extent(extent), forceConstant(forceConstant),
          min(getMinExtent(origin, extent)), max(getMaxExtent(origin, extent)) {}

std::string Box::describe() const {
    return fmt::format("Box potential with origin={}, extent={}, and force constant k={}",
                       origin, extent, forceConstant);
}

std::string Box::type() const {
    return getPotentialName<Box>();
}

/*
 * Sphere Potentials
 */

std::string SphereIn::describe() const {
    return fmt::format("Spherical inclusion potential with origin={}, radius={}, and force constant k={}",
                       origin, radius, forceConstant);
}

std::string SphereIn::type() const {
    return getPotentialName<SphereIn>();
}

std::string SphereOut::describe() const {
    return fmt::format("Spherical exclusion potential with origin={}, radius={}, and force constant k={}",
                       origin, radius, forceConstant);
}

std::string SphereOut::type() const {
    return getPotentialName<SphereOut>();
}

SphericalBarrier::SphericalBarrier(particle_type_type particleType, scalar height, scalar width, const Vec3 &origin, scalar radius)
        : super(particleType), origin(origin), radius(radius), height(height), width(width), r1(radius - width), r2(radius - width / static_cast<scalar>(2.)),
          r3(radius + width / static_cast<scalar>(2.)), r4(radius + width), effectiveForceConstant(static_cast<scalar>(4.) * height / width / width) {
    if (width > radius) {
        throw std::invalid_argument("SphericalBarrier must have a radius larger than its width");
    }
}

std::string SphericalBarrier::describe() const {
    return fmt::format("Spherical barrier potential with origin={}, radius={}, height(energy)={}, and width={}",
                       origin, radius, height, width);
}

std::string SphericalBarrier::type() const {
    return getPotentialName<SphericalBarrier>();
}

/**
 * Cylindrical potentials
 */

CylinderIn::CylinderIn(particle_type_type particleType, scalar forceConstant, const Vec3 &origin, const Vec3 &normal,
                       scalar radius) : super(particleType), forceConstant(forceConstant), origin(origin),
                                        normal(normal/normal.norm()), radius(radius) {
}

std::string CylinderIn::type() const {
    return getPotentialName<CylinderIn>();
}

std::string CylinderIn::describe() const {
    return fmt::format("Cylindrical inclusion potential with force constant={}, origin={}, normal={}, and radius={}",
                       forceConstant, origin, normal, radius);
}

CylinderOut::CylinderOut(particle_type_type particleType, scalar forceConstant, const Vec3 &origin, const Vec3 &normal,
                         scalar radius) : super(particleType), forceConstant(forceConstant), origin(origin),
                                          normal(normal / normal.norm()), radius(radius) {
}

std::string CylinderOut::type() const {
    return getPotentialName<CylinderIn>();
}

std::string CylinderOut::describe() const {
    return fmt::format("Cylindrical exclusion potential with force constant={}, origin={}, normal={}, and radius={}",
                       forceConstant, origin, normal, radius);
}

/////////////////////////////////////////////////////////////////////////////
//
// Potentials order 2
//
/////////////////////////////////////////////////////////////////////////////

/*
 * Harmonic repulsion
 */

std::string HarmonicRepulsion::describe() const {
    return fmt::format("Harmonic repulsion with force constant k={}", _forceConstant);
}

std::string HarmonicRepulsion::type() const {
    return getPotentialName<HarmonicRepulsion>();
}

/**
 * Weak interaction piecewise harmonic
 */

std::string WeakInteractionPiecewiseHarmonic::describe() const {
    return fmt::format("Weak interaction piecewise harmonic potential with force constant k={}, desired distance={}, "
                               "depth={}, and cutoff={}",
                       forceConstant, conf.desiredParticleDistance, conf.depthAtDesiredDistance,
                       conf.noInteractionDistance);
}

std::string WeakInteractionPiecewiseHarmonic::type() const {
    return getPotentialName<HarmonicRepulsion>();
}

WeakInteractionPiecewiseHarmonic::Configuration::Configuration(const scalar  desiredParticleDistance,
                                                               const scalar  depthAtDesiredDistance,
                                                               const scalar  noInteractionDistance)
        : desiredParticleDistance(desiredParticleDistance), depthAtDesiredDistance(depthAtDesiredDistance),
          noInteractionDistance(noInteractionDistance),
          noInteractionDistanceSquared(noInteractionDistance * noInteractionDistance) {}

LennardJones::LennardJones(particle_type_type type1, particle_type_type type2,
                           unsigned int m, unsigned int n, scalar  cutoffDistance,
                           bool shift, scalar  epsilon, scalar  sigma)
        : super(type1, type2), m(m), n(n),
          cutoffDistance(cutoffDistance), shift(shift), epsilon(epsilon), sigma(sigma),
          cutoffDistanceSquared(cutoffDistance * cutoffDistance) {
    if (m <= n) {
        throw std::invalid_argument("When constructing the LJ potential, the first exponent m=" + std::to_string(m) +
                                    " was not greater than the second exponent n=" + std::to_string(n) + "!");
    }
    auto dm = static_cast<scalar >(m);
    auto dn = static_cast<scalar >(n);
    scalar  r_min = sigma * std::pow(dn / dm, c_::one / (dn - dm));
    k = -epsilon / (std::pow(sigma / r_min, dm) - std::pow(sigma / r_min, dn));
}

std::string LennardJones::describe() const {
    std::string withOrWithout = shift ? "with" : "without";
    return fmt::format("{}-{}-Lennard-Jones potential with cutoff={}, epsilon={}, k={}, and {} energy shift",
                       m, n, cutoffDistance, epsilon, k, withOrWithout);
}

std::string LennardJones::type() const {
    return getPotentialName<LennardJones>();
}

ScreenedElectrostatics::ScreenedElectrostatics(particle_type_type type1, particle_type_type type2,
                                               scalar  electrostaticStrength, scalar  inverseScreeningDepth,
                                               scalar  repulsionStrength, scalar  repulsionDistance, unsigned int exponent,
                                               scalar  cutoff)
        : super(type1, type2), electrostaticStrength(electrostaticStrength), inverseScreeningDepth(inverseScreeningDepth),
          repulsionStrength(repulsionStrength), repulsionDistance(repulsionDistance), exponent(exponent), cutoff(cutoff),
          cutoffSquared(cutoff * cutoff) {
    if (inverseScreeningDepth < 0) {
        throw std::invalid_argument("inverse screening depth must be positive!");
    }
    if (repulsionStrength < 0) {
        throw std::invalid_argument("repulsion strength must be positive!");
    }
    if (repulsionDistance < 0) {
        throw std::invalid_argument("repulsion distance must be positive!");
    }
    if (cutoff < 0) {
        throw std::invalid_argument("cutoff must be positive!");
    }
}

std::string ScreenedElectrostatics::describe() const {
    return fmt::format("Screened electrostatics potential with electrostatic strength={}, inverse screening depth={}, "
                               "repulsion strength={}, repulsion distance={}, exponent={}, and cutoff={}",
                       electrostaticStrength, inverseScreeningDepth, repulsionStrength, repulsionDistance,
                       exponent, cutoff);
}

std::string ScreenedElectrostatics::type() const {
    return getPotentialName<ScreenedElectrostatics>();
}

}
}
}
<commit_msg>fix typo<commit_after>/********************************************************************
 * Copyright © 2018 Computational Molecular Biology Group,          *
 *                  Freie Universität Berlin (GER)                  *
 *                                                                  *
 * Redistribution and use in source and binary forms, with or       *
 * without modification, are permitted provided that the            *
 * following conditions are met:                                    *
 *  1. Redistributions of source code must retain the above         *
 *     copyright notice, this list of conditions and the            *
 *     following disclaimer.                                        *
 *  2. Redistributions in binary form must reproduce the above      *
 *     copyright notice, this list of conditions and the following  *
 *     disclaimer in the documentation and/or other materials       *
 *     provided with the distribution.                              *
 *  3. Neither the name of the copyright holder nor the names of    *
 *     its contributors may be used to endorse or promote products  *
 *     derived from this software without specific                  *
 *     prior written permission.                                    *
 *                                                                  *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND           *
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,      *
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF         *
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE         *
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR            *
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     *
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,         *
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,      *
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)    *
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF      *
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                       *
 ********************************************************************/

/**
 * @file Potentials.cpp
 * @brief Core library implementation of order 1 potentials
 * @author clonker
 * @author chrisfroe
 * @date 20.06.16
 */

#include <readdy/model/Kernel.h>
#include <readdy/model/potentials/PotentialsOrder1.h>

namespace readdy {
namespace model {
namespace potentials {

std::string PotentialRegistry::describe() const {
    namespace rus = readdy::util::str;
    auto find_pot_name = [this](ParticleTypeId type) -> const std::string {
        for (auto &&t : _types.get().typeMapping()) {
            if (t.second == type) return t.first;
        }
        return "";
    };
    std::string description;
    if (!potentialsOrder1().empty()) {
        description += fmt::format(" - potentials of order 1:{}", rus::newline);
        for (const auto &types : potentialsOrder1()) {
            description += fmt::format("     * for type \"{}\"{}", find_pot_name(types.first), rus::newline);
            for (auto pot : types.second) {
                description += fmt::format("         * {}{}", pot->describe(), rus::newline);
            }
        }
    }
    if (!potentialsOrder2().empty()) {
        description += fmt::format(" - potentials of order 2:{}", rus::newline);
        for (const auto &types : potentialsOrder2()) {
            description += fmt::format(R"(     * for types "{}" and "{}"{})", find_pot_name(std::get<0>(types.first)),
                                       find_pot_name(std::get<1>(types.first)), rus::newline);
            for (auto pot : types.second) {
                description += fmt::format("         * {}{}", pot->describe(), rus::newline);
            }
        }
    }
    return description;
}

/////////////////////////////////////////////////////////////////////////////
//
// Potentials order 1
//
/////////////////////////////////////////////////////////////////////////////

/**
 * Box potential
 */

Vec3 getMinExtent(const Vec3 &origin, const Vec3 &extent) {
    Vec3 result{0, 0, 0};
    for (auto i = 0; i < 3; i++) {
        if (extent[i] > 0) {
            result[i] = origin[i];
        } else {
            result[i] = origin[i] + extent[i];
        }
    }
    return result;
}

Vec3 getMaxExtent(const Vec3 &origin, const Vec3 &extent) {
    Vec3 result{0, 0, 0};
    for (auto i = 0; i < 3; i++) {
        if (extent[i] > 0) {
            result[i] = origin[i] + extent[i];
        } else {
            result[i] = origin[i];
        }
    }
    return result;
}

Box::Box(particle_type_type particleType, scalar forceConstant, const Vec3 &origin,
                             const Vec3 &extent)
        : super(particleType), origin(origin), extent(extent), forceConstant(forceConstant),
          min(getMinExtent(origin, extent)), max(getMaxExtent(origin, extent)) {}

std::string Box::describe() const {
    return fmt::format("Box potential with origin={}, extent={}, and force constant k={}",
                       origin, extent, forceConstant);
}

std::string Box::type() const {
    return getPotentialName<Box>();
}

/*
 * Sphere Potentials
 */

std::string SphereIn::describe() const {
    return fmt::format("Spherical inclusion potential with origin={}, radius={}, and force constant k={}",
                       origin, radius, forceConstant);
}

std::string SphereIn::type() const {
    return getPotentialName<SphereIn>();
}

std::string SphereOut::describe() const {
    return fmt::format("Spherical exclusion potential with origin={}, radius={}, and force constant k={}",
                       origin, radius, forceConstant);
}

std::string SphereOut::type() const {
    return getPotentialName<SphereOut>();
}

SphericalBarrier::SphericalBarrier(particle_type_type particleType, scalar height, scalar width, const Vec3 &origin, scalar radius)
        : super(particleType), origin(origin), radius(radius), height(height), width(width), r1(radius - width), r2(radius - width / static_cast<scalar>(2.)),
          r3(radius + width / static_cast<scalar>(2.)), r4(radius + width), effectiveForceConstant(static_cast<scalar>(4.) * height / width / width) {
    if (width > radius) {
        throw std::invalid_argument("SphericalBarrier must have a radius larger than its width");
    }
}

std::string SphericalBarrier::describe() const {
    return fmt::format("Spherical barrier potential with origin={}, radius={}, height(energy)={}, and width={}",
                       origin, radius, height, width);
}

std::string SphericalBarrier::type() const {
    return getPotentialName<SphericalBarrier>();
}

/**
 * Cylindrical potentials
 */

CylinderIn::CylinderIn(particle_type_type particleType, scalar forceConstant, const Vec3 &origin, const Vec3 &normal,
                       scalar radius) : super(particleType), forceConstant(forceConstant), origin(origin),
                                        normal(normal/normal.norm()), radius(radius) {
}

std::string CylinderIn::type() const {
    return getPotentialName<CylinderIn>();
}

std::string CylinderIn::describe() const {
    return fmt::format("Cylindrical inclusion potential with force constant={}, origin={}, normal={}, and radius={}",
                       forceConstant, origin, normal, radius);
}

CylinderOut::CylinderOut(particle_type_type particleType, scalar forceConstant, const Vec3 &origin, const Vec3 &normal,
                         scalar radius) : super(particleType), forceConstant(forceConstant), origin(origin),
                                          normal(normal / normal.norm()), radius(radius) {
}

std::string CylinderOut::type() const {
    return getPotentialName<CylinderOut>();
}

std::string CylinderOut::describe() const {
    return fmt::format("Cylindrical exclusion potential with force constant={}, origin={}, normal={}, and radius={}",
                       forceConstant, origin, normal, radius);
}

/////////////////////////////////////////////////////////////////////////////
//
// Potentials order 2
//
/////////////////////////////////////////////////////////////////////////////

/*
 * Harmonic repulsion
 */

std::string HarmonicRepulsion::describe() const {
    return fmt::format("Harmonic repulsion with force constant k={}", _forceConstant);
}

std::string HarmonicRepulsion::type() const {
    return getPotentialName<HarmonicRepulsion>();
}

/**
 * Weak interaction piecewise harmonic
 */

std::string WeakInteractionPiecewiseHarmonic::describe() const {
    return fmt::format("Weak interaction piecewise harmonic potential with force constant k={}, desired distance={}, "
                               "depth={}, and cutoff={}",
                       forceConstant, conf.desiredParticleDistance, conf.depthAtDesiredDistance,
                       conf.noInteractionDistance);
}

std::string WeakInteractionPiecewiseHarmonic::type() const {
    return getPotentialName<HarmonicRepulsion>();
}

WeakInteractionPiecewiseHarmonic::Configuration::Configuration(const scalar  desiredParticleDistance,
                                                               const scalar  depthAtDesiredDistance,
                                                               const scalar  noInteractionDistance)
        : desiredParticleDistance(desiredParticleDistance), depthAtDesiredDistance(depthAtDesiredDistance),
          noInteractionDistance(noInteractionDistance),
          noInteractionDistanceSquared(noInteractionDistance * noInteractionDistance) {}

LennardJones::LennardJones(particle_type_type type1, particle_type_type type2,
                           unsigned int m, unsigned int n, scalar  cutoffDistance,
                           bool shift, scalar  epsilon, scalar  sigma)
        : super(type1, type2), m(m), n(n),
          cutoffDistance(cutoffDistance), shift(shift), epsilon(epsilon), sigma(sigma),
          cutoffDistanceSquared(cutoffDistance * cutoffDistance) {
    if (m <= n) {
        throw std::invalid_argument("When constructing the LJ potential, the first exponent m=" + std::to_string(m) +
                                    " was not greater than the second exponent n=" + std::to_string(n) + "!");
    }
    auto dm = static_cast<scalar >(m);
    auto dn = static_cast<scalar >(n);
    scalar  r_min = sigma * std::pow(dn / dm, c_::one / (dn - dm));
    k = -epsilon / (std::pow(sigma / r_min, dm) - std::pow(sigma / r_min, dn));
}

std::string LennardJones::describe() const {
    std::string withOrWithout = shift ? "with" : "without";
    return fmt::format("{}-{}-Lennard-Jones potential with cutoff={}, epsilon={}, k={}, and {} energy shift",
                       m, n, cutoffDistance, epsilon, k, withOrWithout);
}

std::string LennardJones::type() const {
    return getPotentialName<LennardJones>();
}

ScreenedElectrostatics::ScreenedElectrostatics(particle_type_type type1, particle_type_type type2,
                                               scalar  electrostaticStrength, scalar  inverseScreeningDepth,
                                               scalar  repulsionStrength, scalar  repulsionDistance, unsigned int exponent,
                                               scalar  cutoff)
        : super(type1, type2), electrostaticStrength(electrostaticStrength), inverseScreeningDepth(inverseScreeningDepth),
          repulsionStrength(repulsionStrength), repulsionDistance(repulsionDistance), exponent(exponent), cutoff(cutoff),
          cutoffSquared(cutoff * cutoff) {
    if (inverseScreeningDepth < 0) {
        throw std::invalid_argument("inverse screening depth must be positive!");
    }
    if (repulsionStrength < 0) {
        throw std::invalid_argument("repulsion strength must be positive!");
    }
    if (repulsionDistance < 0) {
        throw std::invalid_argument("repulsion distance must be positive!");
    }
    if (cutoff < 0) {
        throw std::invalid_argument("cutoff must be positive!");
    }
}

std::string ScreenedElectrostatics::describe() const {
    return fmt::format("Screened electrostatics potential with electrostatic strength={}, inverse screening depth={}, "
                               "repulsion strength={}, repulsion distance={}, exponent={}, and cutoff={}",
                       electrostaticStrength, inverseScreeningDepth, repulsionStrength, repulsionDistance,
                       exponent, cutoff);
}

std::string ScreenedElectrostatics::type() const {
    return getPotentialName<ScreenedElectrostatics>();
}

}
}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "DMJsonWriter.h"

#include "SkCommonFlags.h"
#include "SkJSONCPP.h"
#include "SkOSFile.h"
#include "SkStream.h"
#include "SkTArray.h"
#include "SkThread.h"

namespace DM {

SkTArray<JsonWriter::BitmapResult> gBitmapResults;
SK_DECLARE_STATIC_MUTEX(gBitmapResultLock);

void JsonWriter::AddBitmapResult(const BitmapResult& result) {
    SkAutoMutexAcquire lock(&gBitmapResultLock);
    gBitmapResults.push_back(result);
}

SkTArray<skiatest::Failure> gFailures;
SK_DECLARE_STATIC_MUTEX(gFailureLock);

void JsonWriter::AddTestFailure(const skiatest::Failure& failure) {
    SkAutoMutexAcquire lock(gFailureLock);
    gFailures.push_back(failure);
}

void JsonWriter::DumpJson() {
    if (FLAGS_writePath.isEmpty()) {
        return;
    }

    Json::Value root;

    for (int i = 1; i < FLAGS_properties.count(); i += 2) {
        root[FLAGS_properties[i-1]] = FLAGS_properties[i];
    }
    for (int i = 1; i < FLAGS_key.count(); i += 2) {
        root["key"][FLAGS_key[i-1]] = FLAGS_key[i];
    }

    {
        SkAutoMutexAcquire lock(&gBitmapResultLock);
        for (int i = 0; i < gBitmapResults.count(); i++) {
            Json::Value result;
            result["key"]["name"]            = gBitmapResults[i].name.c_str();
            result["key"]["config"]          = gBitmapResults[i].config.c_str();
            result["key"]["mode"]            = gBitmapResults[i].mode.c_str();
            result["options"]["source_type"] = gBitmapResults[i].sourceType.c_str();
            result["md5"]                    = gBitmapResults[i].md5.c_str();

            root["results"].append(result);
        }
    }

    {
        SkAutoMutexAcquire lock(gFailureLock);
        for (int i = 0; i < gFailures.count(); i++) {
            Json::Value result;
            result["file_name"]     = gFailures[i].fileName;
            result["line_no"]       = gFailures[i].lineNo;
            result["condition"]     = gFailures[i].condition;
            result["message"]       = gFailures[i].message.c_str();

            root["test_results"]["failures"].append(result);
        }
    }

    SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json");
    SkFILEWStream stream(path.c_str());
    stream.writeText(Json::StyledWriter().write(root).c_str());
    stream.flush();
}

} // namespace DM
<commit_msg>dm/gold: Let's consider source_type a key.<commit_after>/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "DMJsonWriter.h"

#include "SkCommonFlags.h"
#include "SkJSONCPP.h"
#include "SkOSFile.h"
#include "SkStream.h"
#include "SkTArray.h"
#include "SkThread.h"

namespace DM {

SkTArray<JsonWriter::BitmapResult> gBitmapResults;
SK_DECLARE_STATIC_MUTEX(gBitmapResultLock);

void JsonWriter::AddBitmapResult(const BitmapResult& result) {
    SkAutoMutexAcquire lock(&gBitmapResultLock);
    gBitmapResults.push_back(result);
}

SkTArray<skiatest::Failure> gFailures;
SK_DECLARE_STATIC_MUTEX(gFailureLock);

void JsonWriter::AddTestFailure(const skiatest::Failure& failure) {
    SkAutoMutexAcquire lock(gFailureLock);
    gFailures.push_back(failure);
}

void JsonWriter::DumpJson() {
    if (FLAGS_writePath.isEmpty()) {
        return;
    }

    Json::Value root;

    for (int i = 1; i < FLAGS_properties.count(); i += 2) {
        root[FLAGS_properties[i-1]] = FLAGS_properties[i];
    }
    for (int i = 1; i < FLAGS_key.count(); i += 2) {
        root["key"][FLAGS_key[i-1]] = FLAGS_key[i];
    }

    {
        SkAutoMutexAcquire lock(&gBitmapResultLock);
        for (int i = 0; i < gBitmapResults.count(); i++) {
            Json::Value result;
            result["key"]["name"]        = gBitmapResults[i].name.c_str();
            result["key"]["config"]      = gBitmapResults[i].config.c_str();
            result["key"]["mode"]        = gBitmapResults[i].mode.c_str();
            result["key"]["source_type"] = gBitmapResults[i].sourceType.c_str();
            result["md5"]                = gBitmapResults[i].md5.c_str();

            root["results"].append(result);
        }
    }

    {
        SkAutoMutexAcquire lock(gFailureLock);
        for (int i = 0; i < gFailures.count(); i++) {
            Json::Value result;
            result["file_name"]     = gFailures[i].fileName;
            result["line_no"]       = gFailures[i].lineNo;
            result["condition"]     = gFailures[i].condition;
            result["message"]       = gFailures[i].message.c_str();

            root["test_results"]["failures"].append(result);
        }
    }

    SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json");
    SkFILEWStream stream(path.c_str());
    stream.writeText(Json::StyledWriter().write(root).c_str());
    stream.flush();
}

} // namespace DM
<|endoftext|>


<commit_before>/*
   Copyright 2015 The Trustees of Princeton University

   Licensed under the Apache License, Version 2.0 (the "License" );
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "syndicate-put.h"

#define BUF_SIZE 4096

// entry point
int main( int argc, char** argv ) {

   int rc = 0;
   struct UG_state* ug = NULL;
   struct SG_gateway* gateway = NULL;
   char* path = NULL;
   int path_optind = 0;
   char* file_path = NULL;
   int fd = 0;
   char buf[BUF_SIZE];
   ssize_t nr = 0;
   UG_handle_t* fh = NULL;

   mode_t um = umask(0);
   umask( um );

   struct tool_opts opts;

   memset( &opts, 0, sizeof(tool_opts) );

   rc = parse_args( argc, argv, &opts );
   if( rc != 0 ) {

      usage( argv[0], "local_file syndicate_file" );
      md_common_usage();
      exit(1);
   }

   // setup...
   ug = UG_init( argc, argv, opts.anonymous );
   if( ug == NULL ) {

      SG_error("%s", "UG_init failed\n" );
      exit(1);
   }

   gateway = UG_state_gateway( ug );

   // get the path...
   path_optind = SG_gateway_first_arg_optind( gateway );
   if( path_optind == argc ) {

      usage( argv[0], "local_file syndicate_file" );
      UG_shutdown( ug );
      exit(1);
   }

   // get the file path...
   file_path = argv[ path_optind ];

   // get the syndicate path...
   path_optind++;
   path = argv[path_optind];

   // get the file...
   fd = open( file_path, O_RDONLY );
   if( fd < 0 ) {
      rc = -errno;
      fprintf(stderr, "Failed to open '%s': %s\n", file_path, strerror(-rc));
      rc = 1;
      goto put_end;
   }

   // try to create
   fh = UG_create( ug, path, um & 0777, &rc );
   if( rc != 0 ) {

      if( rc != -EEXIST ) {
          fprintf(stderr, "Failed to create '%s' (%d): %s\n", path, rc, strerror( abs(rc) ) );
          rc = 1;
          goto put_end;
      }
      else {

         // already exists.  open
         fh = UG_open( ug, path, O_WRONLY, &rc );
         if( rc != 0 ) {
            fprintf(stderr, "Failed to open '%s': %d %s\n", path, rc, strerror( abs(rc) ) );
            rc = 1;
            goto put_end;
         }
      }
   }

   // write the file
   while( 1 ) {
      nr = read( fd, buf, 4096 );
      if( nr == 0 ) {
         break;
      }
      if( nr < 0 ) {
         rc = -errno;
         fprintf(stderr, "Failed to read '%s': %s\n", file_path, strerror( abs(rc) ) );
         break;
      }

      rc = UG_write( ug, buf, nr, fh );
      if( rc < 0 ) {

         fprintf(stderr, "Failed to write '%s': %d %s\n", path, rc, strerror( abs(rc) ) );
         break;
      }
   }

   close( fd );

   if( rc < 0 ) {
      rc = 1;
      goto put_end;
   }

   // sync
   rc = UG_fsync( ug, fh );
   if( rc < 0 ) {

      fprintf(stderr, "Failed to fsync '%s': %d %s\n", path, rc, strerror( abs(rc) ) );
      rc = 1;
      goto put_end;
   }

   // close
   rc = UG_close( ug, fh );
   if( rc != 0 ) {
      fprintf(stderr, "Failed to close '%s': %d %s\n", path, rc, strerror( abs(rc) ) );
      rc = 1;
      goto put_end;
   }

put_end:

   UG_shutdown( ug );

   if( rc != 0 ) {
      exit(1);
   }
   else {
      exit(0);
   }
}
<commit_msg>Use mode 0540 when creating files; don't use the umask<commit_after>/*
   Copyright 2015 The Trustees of Princeton University

   Licensed under the Apache License, Version 2.0 (the "License" );
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "syndicate-put.h"

#define BUF_SIZE 4096

// entry point
int main( int argc, char** argv ) {

   int rc = 0;
   struct UG_state* ug = NULL;
   struct SG_gateway* gateway = NULL;
   char* path = NULL;
   int path_optind = 0;
   char* file_path = NULL;
   int fd = 0;
   char buf[BUF_SIZE];
   ssize_t nr = 0;
   UG_handle_t* fh = NULL;

   mode_t um = umask(0);
   umask( um );

   struct tool_opts opts;

   memset( &opts, 0, sizeof(tool_opts) );

   rc = parse_args( argc, argv, &opts );
   if( rc != 0 ) {

      usage( argv[0], "local_file syndicate_file" );
      md_common_usage();
      exit(1);
   }

   // setup...
   ug = UG_init( argc, argv, opts.anonymous );
   if( ug == NULL ) {

      SG_error("%s", "UG_init failed\n" );
      exit(1);
   }

   gateway = UG_state_gateway( ug );

   // get the path...
   path_optind = SG_gateway_first_arg_optind( gateway );
   if( path_optind == argc ) {

      usage( argv[0], "local_file syndicate_file" );
      UG_shutdown( ug );
      exit(1);
   }

   // get the file path...
   file_path = argv[ path_optind ];

   // get the syndicate path...
   path_optind++;
   path = argv[path_optind];

   // get the file...
   fd = open( file_path, O_RDONLY );
   if( fd < 0 ) {
      rc = -errno;
      fprintf(stderr, "Failed to open '%s': %s\n", file_path, strerror(-rc));
      rc = 1;
      goto put_end;
   }

   // try to create
   fh = UG_create( ug, path, 0540, &rc );
   if( rc != 0 ) {

      if( rc != -EEXIST ) {
          fprintf(stderr, "Failed to create '%s' (%d): %s\n", path, rc, strerror( abs(rc) ) );
          rc = 1;
          goto put_end;
      }
      else {

         // already exists.  open
         fh = UG_open( ug, path, O_WRONLY, &rc );
         if( rc != 0 ) {
            fprintf(stderr, "Failed to open '%s': %d %s\n", path, rc, strerror( abs(rc) ) );
            rc = 1;
            goto put_end;
         }
      }
   }

   // write the file
   while( 1 ) {
      nr = read( fd, buf, 4096 );
      if( nr == 0 ) {
         break;
      }
      if( nr < 0 ) {
         rc = -errno;
         fprintf(stderr, "Failed to read '%s': %s\n", file_path, strerror( abs(rc) ) );
         break;
      }

      rc = UG_write( ug, buf, nr, fh );
      if( rc < 0 ) {

         fprintf(stderr, "Failed to write '%s': %d %s\n", path, rc, strerror( abs(rc) ) );
         break;
      }
   }

   close( fd );

   if( rc < 0 ) {
      rc = 1;
      goto put_end;
   }

   // sync
   rc = UG_fsync( ug, fh );
   if( rc < 0 ) {

      fprintf(stderr, "Failed to fsync '%s': %d %s\n", path, rc, strerror( abs(rc) ) );
      rc = 1;
      goto put_end;
   }

   // close
   rc = UG_close( ug, fh );
   if( rc != 0 ) {
      fprintf(stderr, "Failed to close '%s': %d %s\n", path, rc, strerror( abs(rc) ) );
      rc = 1;
      goto put_end;
   }

put_end:

   UG_shutdown( ug );

   if( rc != 0 ) {
      exit(1);
   }
   else {
      exit(0);
   }
}
<|endoftext|>


<commit_before>/**
 * @file connection_sessions_test.cc
 * @author Rafal Slota
 * @copyright (C) 2013 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in 'LICENSE.txt'
 */

#include "testCommon.h"
#include "erlTestCore.h"
#include "boost/filesystem.hpp"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <boost/thread/thread_time.hpp>
#include <cstdlib>

using namespace boost::filesystem;
using namespace std;
using namespace veil::protocol::communication_protocol;
using namespace veil::protocol::fuse_messages;
using namespace veil::client::utils;

INIT_AND_RUN_ALL_TESTS(); // TEST RUNNER !

// TEST definitions below

class ConnectionSessionsTest
: public ::testing::Test
{
protected:
    COMMON_INTEGRATION_DEFS();

    VeilFSMount VFS;

    path directIO_root;

    ConnectionSessionsTest() : VFS("main", "peer.pem")
    {
    }

    virtual void SetUp() {
        COMMON_INTEGRATION_SETUP();
    }

    virtual void TearDown() {
        COMMON_INTEGRATION_CLEANUP();
    }

};

// Test if client negotiates and registers its FuseId after start
TEST_F(ConnectionSessionsTest, SessionInitAndRegister) {
    // By default client should negotiate and register FuseId
    // Check if cluster already knows who we are
    ASSERT_EQ("ok", erlExec(string("{check_session, \"") + config->getFuseID() + string("\"}")));
}

// Test if client can renegotiate FuseId and send env variables
TEST_F(ConnectionSessionsTest, SessionEnvVairables_And_SessionReinitialization) {
    // By default client should negotiate and register FuseId

    string currentFuseId = config->getFuseID();
    // Now we can manually add some env varables
    config->putEnv(FUSE_OPT_PREFIX + "varname1","varvalue1");
    config->putEnv(FUSE_OPT_PREFIX + "varname2","varvalue2");

    // Start new handshake
    config->negotiateFuseID();

    sleep(10); // This can take a while

    // New session ID (FuseId) shall be different from previous
    ASSERT_NE(currentFuseId, config->getFuseID());

    // Check if session variables are in place (in DB)
    ASSERT_EQ("ok", erlExec(string("{check_session_variables, \"") + config->getFuseID() + string("\", [{varname1, \"varvalue1\"}, {varname2, \"varvalue2\"}]}")));
}

<commit_msg>compilation fix<commit_after>/**
 * @file connection_sessions_test.cc
 * @author Rafal Slota
 * @copyright (C) 2013 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in 'LICENSE.txt'
 */

#include "testCommon.h"
#include "erlTestCore.h"
#include "boost/filesystem.hpp"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <boost/thread/thread_time.hpp>
#include <cstdlib>

using namespace boost::filesystem;
using namespace std;
using namespace veil::protocol::communication_protocol;
using namespace veil::protocol::fuse_messages;
using namespace veil::client::utils;

INIT_AND_RUN_ALL_TESTS(); // TEST RUNNER !

// TEST definitions below

class ConnectionSessionsTest
: public ::testing::Test
{
protected:
    COMMON_INTEGRATION_DEFS();

    VeilFSMount VFS;

    path directIO_root;

    ConnectionSessionsTest() : VFS("main", "peer.pem")
    {
    }

    virtual void SetUp() {
        COMMON_INTEGRATION_SETUP();
    }

    virtual void TearDown() {
        COMMON_INTEGRATION_CLEANUP();
    }

};

// Test if client negotiates and registers its FuseId after start
TEST_F(ConnectionSessionsTest, SessionInitAndRegister) {
    // By default client should negotiate and register FuseId
    // Check if cluster already knows who we are
    ASSERT_EQ("ok", erlExec(string("{check_session, \"") + config->getFuseID() + string("\"}")));
}

// Test if client can renegotiate FuseId and send env variables
TEST_F(ConnectionSessionsTest, SessionEnvVairables_And_SessionReinitialization) {
    // By default client should negotiate and register FuseId

    string currentFuseId = config->getFuseID();
    // Now we can manually add some env varables
    config->putEnv(string(FUSE_OPT_PREFIX) + string("varname1"),"varvalue1");
    config->putEnv(string(FUSE_OPT_PREFIX) + string("varname2"),"varvalue2");

    // Start new handshake
    config->negotiateFuseID();

    sleep(10); // This can take a while

    // New session ID (FuseId) shall be different from previous
    ASSERT_NE(currentFuseId, config->getFuseID());

    // Check if session variables are in place (in DB)
    ASSERT_EQ("ok", erlExec(string("{check_session_variables, \"") + config->getFuseID() + string("\", [{varname1, \"varvalue1\"}, {varname2, \"varvalue2\"}]}")));
}

<|endoftext|>


<commit_before>//===-- io.cpp ------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// I/O routines for registered fd's
//
//===----------------------------------------------------------------------===//

#include "ipcopt.h"

#include "debug.h"
#include "ipcreg_internal.h"
#include "socket_inline.h"
#include "ipcd.h"

#include <cassert>

const size_t TRANS_THRESHOLD = 1ULL << 20;

void copy_bufsize(int src, int dst, int buftype) {
  int bufsize;
  socklen_t sz = sizeof(bufsize);
  int ret = getsockopt(src, SOL_SOCKET, buftype, &bufsize, &sz);
  assert(!ret);
  // ipclog("Bufsize %d of fd %d: %d\n", buftype, src, bufsize);
  ret = setsockopt(dst, SOL_SOCKET, buftype, &bufsize, sz);
  assert(!ret);
}
void copy_bufsizes(int src, int dst) {
  copy_bufsize(src, dst, SO_RCVBUF);
  copy_bufsize(src, dst, SO_SNDBUF);
}

typedef ssize_t (*IOFunc)(...);

template <typename buf_t>
ssize_t do_ipc_io(int fd, buf_t buf, size_t count, int flags, IOFunc IO) {
  ipc_info *i = getFDDesc(fd);
  assert(i->valid);

  // If localized, just use fast socket:
  if (i->state == STATE_OPTIMIZED) {
    return IO(i->localfd, buf, count, flags);
  }

  // Otherwise, send on original fd:
  ssize_t ret = IO(fd, buf, count, flags);

  // We don't handle other states yet
  assert(i->state == STATE_UNOPT);

  if (ret == -1)
    return ret;

  // Successful operation, add to running total.
  i->bytes_trans += ret;

  if (i->bytes_trans > TRANS_THRESHOLD) {
    ipclog("IO of %zu bytes crosses threshold for fd=%d\n", i->bytes_trans, fd);

    // Fake localization of this for now:
    i->localfd = fd;
    i->state = STATE_OPTIMIZED;
  }

  return ret;
}

ssize_t do_ipc_send(int fd, const void *buf, size_t count, int flags) {
  return do_ipc_io(fd, buf, count, flags, (IOFunc)__real_send);
}

ssize_t do_ipc_recv(int fd, void *buf, size_t count, int flags) {
  return do_ipc_io(fd, buf, count, flags, (IOFunc)__real_recv);
}

ssize_t do_ipc_sendto(int fd, const void *message, size_t length, int flags,
                      const struct sockaddr *dest_addr,
                      socklen_t /* unused */) {
  // if (dest_addr)
  //  return __real_sendto(fd, message, length, flags, dest_addr, dest_len);
  // Hardly safe, but if it's non-NULL there's a chance
  // the caller might want us to write something there.
  assert(!dest_addr);

  // As a bonus from the above check, we can forward to plain send()
  return do_ipc_send(fd, message, length, flags);
}
ssize_t do_ipc_recvfrom(int fd, void *buffer, size_t length, int flags,
                        struct sockaddr *address, socklen_t * /* unused */) {
  // if (address)
  //  return __real_recvfrom(fd, buffer, length, flags, address, address_len);
  // Hardly safe, but if it's non-NULL there's a chance
  // the caller might want us to write something there.
  assert(!address);

  // As a bonus from the above check, we can forward to plain recv()
  return do_ipc_recv(fd, buffer, length, flags);
}
<commit_msg>fix minor comment mistake when merging send/recv<commit_after>//===-- io.cpp ------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// I/O routines for registered fd's
//
//===----------------------------------------------------------------------===//

#include "ipcopt.h"

#include "debug.h"
#include "ipcreg_internal.h"
#include "socket_inline.h"
#include "ipcd.h"

#include <cassert>

const size_t TRANS_THRESHOLD = 1ULL << 20;

void copy_bufsize(int src, int dst, int buftype) {
  int bufsize;
  socklen_t sz = sizeof(bufsize);
  int ret = getsockopt(src, SOL_SOCKET, buftype, &bufsize, &sz);
  assert(!ret);
  // ipclog("Bufsize %d of fd %d: %d\n", buftype, src, bufsize);
  ret = setsockopt(dst, SOL_SOCKET, buftype, &bufsize, sz);
  assert(!ret);
}
void copy_bufsizes(int src, int dst) {
  copy_bufsize(src, dst, SO_RCVBUF);
  copy_bufsize(src, dst, SO_SNDBUF);
}

typedef ssize_t (*IOFunc)(...);

template <typename buf_t>
ssize_t do_ipc_io(int fd, buf_t buf, size_t count, int flags, IOFunc IO) {
  ipc_info *i = getFDDesc(fd);
  assert(i->valid);

  // If localized, just use fast socket:
  if (i->state == STATE_OPTIMIZED) {
    return IO(i->localfd, buf, count, flags);
  }

  // Otherwise, use original fd:
  ssize_t ret = IO(fd, buf, count, flags);

  // We don't handle other states yet
  assert(i->state == STATE_UNOPT);

  if (ret == -1)
    return ret;

  // Successful operation, add to running total.
  i->bytes_trans += ret;

  if (i->bytes_trans > TRANS_THRESHOLD) {
    ipclog("IO of %zu bytes crosses threshold for fd=%d\n", i->bytes_trans, fd);

    // Fake localization of this for now:
    i->localfd = fd;
    i->state = STATE_OPTIMIZED;
  }

  return ret;
}

ssize_t do_ipc_send(int fd, const void *buf, size_t count, int flags) {
  return do_ipc_io(fd, buf, count, flags, (IOFunc)__real_send);
}

ssize_t do_ipc_recv(int fd, void *buf, size_t count, int flags) {
  return do_ipc_io(fd, buf, count, flags, (IOFunc)__real_recv);
}

ssize_t do_ipc_sendto(int fd, const void *message, size_t length, int flags,
                      const struct sockaddr *dest_addr,
                      socklen_t /* unused */) {
  // if (dest_addr)
  //  return __real_sendto(fd, message, length, flags, dest_addr, dest_len);
  // Hardly safe, but if it's non-NULL there's a chance
  // the caller might want us to write something there.
  assert(!dest_addr);

  // As a bonus from the above check, we can forward to plain send()
  return do_ipc_send(fd, message, length, flags);
}
ssize_t do_ipc_recvfrom(int fd, void *buffer, size_t length, int flags,
                        struct sockaddr *address, socklen_t * /* unused */) {
  // if (address)
  //  return __real_recvfrom(fd, buffer, length, flags, address, address_len);
  // Hardly safe, but if it's non-NULL there's a chance
  // the caller might want us to write something there.
  assert(!address);

  // As a bonus from the above check, we can forward to plain recv()
  return do_ipc_recv(fd, buffer, length, flags);
}
<|endoftext|>