/* Copyright (C) 2000-2004 Code contributed by Greg Collecutt, Joseph Hope and Paul Cochrane This file is part of xmds. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* $Id: xmdsfield.cc,v 1.32 2005/04/27 05:44:19 joehope Exp $ */ /*! @file xmdsfield.cc @brief Field element parsing classes and methods More detailed explanation... */ #include #include #include #include // ****************************************************************************** // ****************************************************************************** // xmdsFieldGeometry // ****************************************************************************** // ****************************************************************************** extern bool debugFlag; // ****************************************************************************** void xmdsFieldGeometry::clear() { if(debugFlag) { printf("xmdsFieldGeometry::clear\n"); } myDimensionsList.clear(); }; // ****************************************************************************** unsigned long xmdsFieldGeometry::nDims() const { if(debugFlag) { printf("xmdsFieldGeometry::nDims\n"); } return myDimensionsList.size(); }; // ****************************************************************************** const dimensionStruct* xmdsFieldGeometry::dimension( const unsigned long& index) const { if(debugFlag) { printf("xmdsFieldGeometry::dimension\n"); } if(index>=myDimensionsList.size()) { throw xmdsException("Internal range error in xmdsFieldGeometry::dimension"); } list::const_iterator pdimensionStruct = myDimensionsList.begin(); for(unsigned long i=0; imyDimensionsList.size()) { throw xmdsException("Internal range error in xmdsFieldGeometry::setDimension"); } if(index==myDimensionsList.size()) { myDimensionsList.push_back(newDimension); } list::iterator pdimensionStruct = myDimensionsList.begin(); for(unsigned long i=0; i::const_iterator pDim = myDimensionsList.begin(); pDim != myDimensionsList.end(); pDim++) { if(pDim->name == dimName) { dimNumber=i; return 1; } i++; } return 0; }; // ****************************************************************************** unsigned long xmdsFieldGeometry::fullSpace() const { if(debugFlag) { printf("xmdsFieldGeometry::fullSpace\n"); } unsigned long two2n=1; for(unsigned long i=0; i::const_iterator ppxmdsVector = myVectorsList.begin(); ppxmdsVector != myVectorsList.end(); ppxmdsVector++) { delete (*ppxmdsVector); } }; // ****************************************************************************** void xmdsField::processElement( const Element *const yourElement) { if(debugFlag) { printf("xmdsField::processElement\n"); } if(verbose()) { printf("Processing field element ...\n"); } myNeedsFFTWPlans=0; list anXMLStringList; list::const_iterator pXMLString; // ************************************ // find name getAssignmentStrings(yourElement,"name",0,1,anXMLStringList); if(anXMLStringList.size()==1) { myName = *anXMLStringList.begin(); if(verbose()) { printf("field name is '%s'\n",myName.c_str()); } } else { myName = "main"; printf("field name defaulting to '%s'\n",myName.c_str()); } list aLatticeList; list::const_iterator pULong; list aDomainList; list::const_iterator pDomain; // ************************************ // find transverse dimensions getAssignmentStrings(yourElement,"dimensions",0,0,anXMLStringList); if(anXMLStringList.size()>63) { throw xmdsException(yourElement,"xmds currently limited to 63 transverse dimensions"); } if(anXMLStringList.size()>0) { unsigned long i; // ************************************ // find transverse lattice getAssignmentULongs(yourElement,"lattice",1,anXMLStringList.size(),aLatticeList); i=0; for(pULong = aLatticeList.begin(); pULong != aLatticeList.end(); pULong++) { if(*pULong < 2) { sprintf(errorMessage(), "lattice for dimension #%li must be > 1",i+1); throw xmdsException(yourElement,errorMessage()); } if(verbose()) { printf("transverse lattice #%li has %li points\n",i+1,*pULong); } i++; } // ************************************ // find transverse domains getAssignmentDomains(yourElement,"domains",1,anXMLStringList.size(),aDomainList); if(verbose()) { i=0; for(pDomain = aDomainList.begin(); pDomain != aDomainList.end(); pDomain++) { printf("transverse domain #%li:\n",i+1); printf(" begin = %f\n",pDomain->begin); printf(" end = %f\n",pDomain->end); i++; } } } else { if(verbose()) { printf("No transverse dimensions found.\n"); } } // build field geometry dimensions myGeometry.clear(); pXMLString = anXMLStringList.begin(); pULong = aLatticeList.begin(); pDomain = aDomainList.begin(); for(unsigned long i=0; i< anXMLStringList.size(); i++) { dimensionStruct nextDimension; for(unsigned long j=0;jname) { sprintf(errorMessage(),"duplicate dimension '%s'",pXMLString->c_str()); throw xmdsException(yourElement,errorMessage()); } } if(verbose()) { printf("adding transverse dimension '%s'\n",pXMLString->c_str()); } nextDimension.name = *pXMLString; nextDimension.lattice = *pULong; nextDimension.domain = *pDomain; myGeometry.addDimension(nextDimension); pXMLString++; pULong++; pDomain++; } // ************************************ // find samples getAssignmentULongs(yourElement,"samples",1,0,mySamplesList); // ************************************ // find and process vector elements // ************************************ const NodeList* candidateElements; candidateElements = yourElement->getElementsByTagName("vector",0); if(candidateElements->length()==0) { throw xmdsException(yourElement,"at least one vector expected"); } for(unsigned long i=0; ilength(); i++) { const Element* nextElement = dynamic_cast(candidateElements->item(i)); xmdsElement* newxmdsVectorElement = createxmdsVectorElement(); newxmdsVectorElement->processElement(nextElement); } }; // ****************************************************************************** void xmdsField::processVectors( const list& vectorNamesList, const unsigned long& space) const { if(debugFlag) { printf("xmdsField::processVectors\n"); } for(list::const_iterator pXMLString = vectorNamesList.begin(); pXMLString != vectorNamesList.end(); pXMLString++) { const xmdsVector* nextVector; if(!getVector(*pXMLString,nextVector)) { sprintf(errorMessage(),"Vector '%s' unknown",pXMLString->c_str()); throw xmdsException(errorMessage()); } for(list::const_iterator pXMLString2 = vectorNamesList.begin(); pXMLString2 != pXMLString; pXMLString2++) { if(*pXMLString == *pXMLString2) { sprintf(errorMessage(),"Duplicate vector '%s'",pXMLString->c_str()); throw xmdsException(errorMessage()); } } if(nextVector->initialSpace() != space){ if(nextVector->vectorType() != COMPLEX) { const char* spaceDescription; if(space == 0) { spaceDescription = "x-space"; } else if(space == myGeometry.fullSpace()) { spaceDescription = "k-space"; } else { spaceDescription = "mixed fourier space"; } sprintf(errorMessage(),"Cannot convert vector '%s' to %s since it is not of type 'complex'", pXMLString->c_str(),spaceDescription); throw xmdsException(errorMessage()); } myNeedsFFTWPlans = 1; nextVector->setNeedsFFTWRoutines(); } // Always write FFTW Plans for main vector // (otherwise a rare exception for deterministic MPI which uses FFTW to split field across processes) // Could make this MPI specifc, or else define the appropriate if(pXMLString->c_str()=="main") myNeedsFFTWPlans = 1; if(verbose()) { printf("adding vector '%s' to accessible vectors list\n",pXMLString->c_str()); } } }; // ****************************************************************************** void xmdsField::outputSampleCount() const { if(debugFlag) { printf("xmdsField::outputSampleCount\n"); } if(mySamplesList.size() != simulation()->output()->nMomentGroups()) { throw xmdsException("number of samples in field element does not match number of output moment groups"); } simulation()->output()->addSamples(mySamplesList); }; // ****************************************************************************** bool xmdsField::needsFFTWPlans() const { if(debugFlag) { printf("xmdsField::needsFFTWPlans\n"); } return myNeedsFFTWPlans; }; // ****************************************************************************** void xmdsField::writeInitialisationCalls( FILE *const outfile, const char *const indent) const { if(debugFlag) { printf("xmdsField::writeInitialisationCalls\n"); } for(list::const_iterator ppxmdsVector = myVectorsList.begin(); ppxmdsVector != myVectorsList.end(); ppxmdsVector++) { (*ppxmdsVector)->writeInitialisationCall(outfile,indent); } fprintf(outfile,"\n"); }; // ****************************************************************************** void xmdsField::writeSampleCalls( FILE *const outfile, const char *const indent) const { if(debugFlag) { printf("xmdsField::writeSampleCalls\n"); } unsigned long i=0; for(list::const_iterator pULong = mySamplesList.begin(); pULong != mySamplesList.end(); pULong++) { if(*pULong>0) { fprintf(outfile,"%s_mg%li_sample();\n",indent,i); } i++; } fprintf(outfile,"\n"); }; // ****************************************************************************** void xmdsField::assignActiveVectorPointers( FILE *const outfile, const char *const tempVectorName) const { if(debugFlag) { printf("xmdsField::assignActiveVectorPointers\n"); } for(list::const_iterator ppxmdsVector = myVectorsList.begin(); ppxmdsVector != myVectorsList.end(); ppxmdsVector++) { fprintf(outfile,"_active_%s_%s = %s_%s_%s;\n", myName.c_str(),(*ppxmdsVector)->name()->c_str(),tempVectorName,myName.c_str(),(*ppxmdsVector)->name()->c_str()); } fprintf(outfile,"\n"); }; // ****************************************************************************** const XMLString* xmdsField::name() const { if(debugFlag) { printf("xmdsField::name\n"); } return &myName; }; // ****************************************************************************** const xmdsFieldGeometry* xmdsField::geometry() const{ if(debugFlag) { printf("xmdsField::geometry\n"); } return &myGeometry; }; // ****************************************************************************** bool xmdsField::getVector( const XMLString& vectorName, const xmdsVector*& theVector) const { if(debugFlag) { printf("xmdsField::getVector\n"); } theVector=0; for(list::const_iterator ppxmdsVector = myVectorsList.begin(); ppxmdsVector != myVectorsList.end(); ppxmdsVector++) { if(*(*ppxmdsVector)->name()==vectorName) { theVector = *ppxmdsVector; return 1; } } return 0; }; // ****************************************************************************** void xmdsField::vectorNames( list& vectorNamesList) const { if(debugFlag) { printf("xmdsField::vectorNames\n"); } vectorNamesList.clear(); for(list::const_iterator ppxmdsVector = myVectorsList.begin(); ppxmdsVector != myVectorsList.end(); ppxmdsVector++) { vectorNamesList.push_back(*(*ppxmdsVector)->name()); } }; // ****************************************************************************** void xmdsField::vectors2space( FILE *const outfile, const unsigned long& space, const list& vectorNamesList, const char *const indent) const { if(debugFlag) { printf("xmdsField::vectors2space\n"); } if(myGeometry.nDims()==0) { return; } for(list::const_iterator pXMLString = vectorNamesList.begin(); pXMLString != vectorNamesList.end(); pXMLString++) { const xmdsVector* nextVector; if(!getVector(*pXMLString,nextVector)) { throw xmdsException("Internal error in xmdsField::vectors2space: cannot find vector"); } if(nextVector->needsFFTWRoutines()) { fprintf(outfile,"%s_%s_%s_go_space(%li);\n",indent,myName.c_str(),pXMLString->c_str(),space); fprintf(outfile,"\n"); } } }; // ****************************************************************************** void xmdsField::openLoops( FILE *const outfile, unsigned long space, const list& vectorNamesList) const { if(debugFlag) { printf("xmdsField::openLoops\n"); } for(list::const_iterator pXMLString = vectorNamesList.begin(); pXMLString != vectorNamesList.end(); pXMLString++) { fprintf(outfile,"unsigned long _%s_%s_index_pointer=0;\n",myName.c_str(),pXMLString->c_str()); } fprintf(outfile,"\n"); bool swapped=false; if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { if((space&1)&((space>>1)&1)) { swapped=true; } } if((!simulation()->parameters()->stochastic)&(simulation()->parameters()->usempi)&swapped) { fprintf(outfile, "double k%s = local_y_start_after_transpose*_%s_dk1;\n" "if(k%s>((_%s_lattice1-1)/2 + 0.1)*_%s_dk1)\n" " k%s -= _%s_lattice1*_%s_dk1;\n" "\n" "for(long _i0=0; _i0name.c_str(),myName.c_str(), myGeometry.dimension(1)->name.c_str(),myName.c_str(),myName.c_str(), myGeometry.dimension(1)->name.c_str(),myName.c_str(),myName.c_str()); space >>= 1; fprintf(outfile, " " "double k%s = 0;\n" "\n" " " "for(long _i1=0; _i1<_%s_lattice0; _i1++) {\n" "\n", myGeometry.dimension(0)->name.c_str(), myName.c_str()); space >>= 1; for(unsigned long i=2; iname.c_str()); } else { fprintf(outfile,"double %s = _%s_xmin%li;\n",myGeometry.dimension(i)->name.c_str(),myName.c_str(),i); } fprintf(outfile,"\n"); for(unsigned long j=0; j>= 1; } } else if((!simulation()->parameters()->stochastic)&(simulation()->parameters()->usempi)) { if(space&1) { fprintf(outfile,"double k%s = local_x_start*_%s_dk0;\n",myGeometry.dimension(0)->name.c_str(),myName.c_str()); fprintf(outfile,"if(k%s>((_%s_lattice0-1)/2 + 0.1)*_%s_dk0)\n", myGeometry.dimension(0)->name.c_str(),myName.c_str(),myName.c_str()); fprintf(outfile," k%s -= _%s_lattice0*_%s_dk0;\n", myGeometry.dimension(0)->name.c_str(),myName.c_str(),myName.c_str()); } else fprintf(outfile,"double %s = _%s_xmin0+local_x_start*_%s_dx0;\n",myGeometry.dimension(0)->name.c_str(),myName.c_str(),myName.c_str()); fprintf(outfile,"\n"); fprintf(outfile,"for(long _i0=0; _i0>= 1; for(unsigned long i=1; iname.c_str()); } else { fprintf(outfile,"double %s = _%s_xmin%li;\n",myGeometry.dimension(i)->name.c_str(),myName.c_str(),i); } fprintf(outfile,"\n"); for(unsigned long j=0; j>= 1; } } else { for(unsigned long i=0; iname.c_str()); } else { fprintf(outfile,"double %s = _%s_xmin%li;\n",myGeometry.dimension(i)->name.c_str(),myName.c_str(),i); } fprintf(outfile,"\n"); for(unsigned long j=0; j>= 1; } } }; // ****************************************************************************** void xmdsField::closeLoops( FILE *const outfile, unsigned long space, const list& vectorNamesList) const { if(debugFlag) { printf("xmdsField::closeLoops\n"); } if(myGeometry.nDims()>0) { fprintf(outfile,"\n"); for(list::const_iterator pXMLString = vectorNamesList.begin(); pXMLString != vectorNamesList.end(); pXMLString++) { for(unsigned long j=0; jc_str(),myName.c_str(),pXMLString->c_str()); } } bool *isKSpace = new bool[myGeometry.nDims()]; unsigned long tempSpace = space; for(long unsigned int i=0; i>=1; } bool swapped=false; if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { if((space&1)&((space>>1)&1)) { swapped=true; } } if((!simulation()->parameters()->stochastic)&(simulation()->parameters()->usempi)&swapped) { for(unsigned long i=myGeometry.nDims(); i>2; i--) { fprintf(outfile,"\n"); if(isKSpace[i-1]) { for(unsigned long j=0; jname.c_str(),myName.c_str(),i-1); for(unsigned long j=0; j((_%s_lattice%li-1)/2 + 0.1)*_%s_dk%li)\n", myGeometry.dimension(i-1)->name.c_str(),myName.c_str(),i-1,myName.c_str(),i-1); for(unsigned long j=0; jname.c_str(),myName.c_str(),i-1,myName.c_str(),i-1); } else { for(unsigned long j=0; jname.c_str(),myName.c_str(),i-1); } for(unsigned long j=0; jname.c_str(),myName.c_str()); for(unsigned long j=0; j<2; j++) { fprintf(outfile," "); } fprintf(outfile,"if(k%s>((_%s_lattice0-1)/2 + 0.1)*_%s_dk0)\n", myGeometry.dimension(0)->name.c_str(),myName.c_str(),myName.c_str()); for(unsigned long j=0; j<2; j++) { fprintf(outfile," "); } fprintf(outfile," k%s -= _%s_lattice0*_%s_dk0;\n", myGeometry.dimension(0)->name.c_str(),myName.c_str(),myName.c_str()); for(unsigned long j=0; j<2; j++) { fprintf(outfile," "); } fprintf(outfile,"}\n"); fprintf(outfile,"\n"); fprintf(outfile," "); fprintf(outfile,"k%s += _%s_dk1;\n",myGeometry.dimension(1)->name.c_str(),myName.c_str()); fprintf(outfile," "); fprintf(outfile,"if(k%s>((_%s_lattice1-1)/2 + 0.1)*_%s_dk1)\n", myGeometry.dimension(1)->name.c_str(),myName.c_str(),myName.c_str()); fprintf(outfile," "); fprintf(outfile," k%s -= _%s_lattice1*_%s_dk1;\n", myGeometry.dimension(1)->name.c_str(),myName.c_str(),myName.c_str()); fprintf(outfile," "); fprintf(outfile,"}\n"); } else { for(unsigned long i=myGeometry.nDims(); i>0; i--) { fprintf(outfile,"\n"); if(isKSpace[i-1]) { for(unsigned long j=0; jname.c_str(),myName.c_str(),i-1); for(unsigned long j=0; j((_%s_lattice%li-1)/2 + 0.1)*_%s_dk%li)\n", myGeometry.dimension(i-1)->name.c_str(),myName.c_str(),i-1,myName.c_str(),i-1); for(unsigned long j=0; jname.c_str(),myName.c_str(),i-1,myName.c_str(),i-1); } else { for(unsigned long j=0; jname.c_str(),myName.c_str(),i-1); } for(unsigned long j=0; jparameters()->simulationName.c_str(); if(useFFTWMeasure) { useMeasureStr = "|FFTW_MEASURE"; } if(useWisdom) { useWisdomStr = "|FFTW_USE_WISDOM"; } for(unsigned long i=0;iparameters()->stochastic))&(simulation()->parameters()->usempi)){ if (useWisdom) { fprintf(outfile, "{\n" "\nFILE *fWisdom;\n" "ifstream fIn;\n" "ofstream fOut;\n" "// this is a dodgy hack, but it should work\n" "string findHostString, findHomeString, hostStuff, homeStuff, rmString, rankString;\n" "ostringstream outString;\n" "outString << rank;\n" "rankString = outString.str();\n" "hostStuff = \"host_rank_\" + rankString + \".stuff\";\n" "findHostString = \"uname -n > \" + hostStuff;\n" "system(findHostString.c_str());\n" "homeStuff = \"home_rank_\" + rankString + \".stuff\";\n" "findHomeString = \"echo $HOME > \" + homeStuff;\n" "system(findHomeString.c_str());\n" "string hostName, homeDir;\n" "fIn.open(hostStuff.c_str());\n" "if (fIn.fail()) {\n" " // do something\n" "}\n" "fIn >> hostName;\n" "fIn.close();\n" "fIn.open(homeStuff.c_str());\n" "if (fIn.fail()) {\n" " // do something\n" "}\n" "fIn >> homeDir;\n" "fIn.close();\n" "rmString = \"rm \" + hostStuff + \" \" + homeStuff;\n" "system(rmString.c_str());\n\n" "string testFname, wisdomFname;\n" "testFname = homeDir + \"/.xmds/wisdom/test-\" + rankString;\n" "fOut.open(testFname.c_str());\n" "if (fOut.fail()) {\n" " cout << \"Warning: ~/.xmds/wisdom directory doesn't seem to exist.\\n\";\n" " cout << \"Using current directory instead\\n\";\n" " wisdomFname = hostName + \".wisdom\";\n" "}\n" "else {\n" " fOut.close();\n" " rmString = \"rm \" + testFname;\n" " system(rmString.c_str());\n" " wisdomFname = homeDir + \"/.xmds/wisdom/\" + hostName + \".wisdom\";\n" "}\n" "printf(\"Performing fftw calculations\\n\");\n" "if ((fWisdom = fopen(wisdomFname.c_str(), \"r\")) != NULL) {\n" " cout << \"Standing upon the shoulders of giants... (Importing wisdom)\\n\";\n" " fftw_import_wisdom_from_file(fWisdom);\n" " fclose(fWisdom);\n" "}\n" ); } fprintf(outfile,"printf(\"Making forward plan\\n\");\n"); fprintf(outfile,"_%s_forward_plan = fftwnd_mpi_create_plan(MPI_COMM_WORLD,_%s_ndims,_fftw_lattice,FFTW_FORWARD,FFTW_IN_PLACE%s%s);\n",myName.c_str(),myName.c_str(),useMeasureStr,useWisdomStr); // Using FFTW_TRANSPOSED_ORDER, so backward plan has different array sizes fprintf(outfile,"_fftw_lattice[0]=_%s_lattice1;\n",myName.c_str()); fprintf(outfile,"_fftw_lattice[1]=_%s_lattice0;\n",myName.c_str()); for(unsigned long i=2;iparameters()->usempi) { fprintf(outfile, "int rank = 0;\n"); } fprintf(outfile, "ostringstream outString;\n" "outString << rank;\n" "rankString = outString.str();\n" "hostStuff = \"host_rank_\" + rankString + \".stuff\";\n" "findHostString = \"uname -n > \" + hostStuff;\n" "system(findHostString.c_str());\n" "homeStuff = \"home_rank_\" + rankString + \".stuff\";\n" "findHomeString = \"echo $HOME > \" + homeStuff;\n" "system(findHomeString.c_str());\n" "string hostName, homeDir;\n" "fIn.open(hostStuff.c_str());\n" "if (fIn.fail()) {\n" " // do something\n" "}\n" "fIn >> hostName;\n" "fIn.close();\n" "fIn.open(homeStuff.c_str());\n" "if (fIn.fail()) {\n" " // do something\n" "}\n" "fIn >> homeDir;\n" "fIn.close();\n" "rmString = \"rm \" + hostStuff + \" \" + homeStuff;\n" "system(rmString.c_str());\n\n" "string testFname, wisdomFname;\n" "testFname = homeDir + \"/.xmds/wisdom/test-\" + rankString;\n" "fOut.open(testFname.c_str());\n" "if (fOut.fail()) {\n" " cout << \"Warning: ~/.xmds/wisdom directory doesn't seem to exist.\\n\";\n" " cout << \"Using current directory instead\\n\";\n" " wisdomFname = hostName + \".wisdom\";\n" "}\n" "else {\n" " fOut.close();\n" " wisdomFname = homeDir + \"/.xmds/wisdom/\" + hostName + \".wisdom\";\n" " rmString = \"rm \" + testFname;\n" " system(rmString.c_str());\n" "}\n" "printf(\"Performing fftw calculations\\n\");\n" "if ( (fWisdom = fopen(wisdomFname.c_str(), \"r\")) != NULL) {\n" " cout << \"Standing upon the shoulders of giants... (Importing wisdom)\\n\";\n" " fftw_import_wisdom_from_file(fWisdom);\n" " fclose(fWisdom);\n" "}\n"); } fprintf(outfile,"printf(\"Making forward plan\\n\");\n"); fprintf(outfile,"_%s_forward_plan = fftwnd_create_plan(_%s_ndims,_fftw_lattice,FFTW_FORWARD,FFTW_IN_PLACE%s%s);\n",myName.c_str(),myName.c_str(),useMeasureStr,useWisdomStr); fprintf(outfile,"printf(\"Making backward plan\\n\");\n"); fprintf(outfile,"_%s_backward_plan = fftwnd_create_plan(_%s_ndims,_fftw_lattice,FFTW_BACKWARD,FFTW_IN_PLACE%s%s);\n",myName.c_str(),myName.c_str(),useMeasureStr,useWisdomStr); if (useWisdom) { fprintf(outfile, "printf(\"Keeping accumulated wisdom\\n\");\n" "fWisdom = fopen(wisdomFname.c_str(),\"w\");\n" "fftw_export_wisdom_to_file(fWisdom);\n" "fclose(fWisdom);\n" "}\n" "printf(\"Finished fftw calculations\\n\");\n"); } } fprintf(outfile,"\n"); }; // ****************************************************************************** void xmdsField::writePlanDeletionCalls( FILE *const outfile) const { if(debugFlag) { printf("xmdsField::writePlanDeletionCalls\n"); } if(!myNeedsFFTWPlans) { return; } if((!(simulation()->parameters()->stochastic))&(simulation()->parameters()->usempi)){ fprintf(outfile,"fftwnd_mpi_destroy_plan(_%s_forward_plan);\n",myName.c_str()); fprintf(outfile,"fftwnd_mpi_destroy_plan(_%s_backward_plan);\n",myName.c_str()); } else { fprintf(outfile,"fftwnd_destroy_plan(_%s_forward_plan);\n",myName.c_str()); fprintf(outfile,"fftwnd_destroy_plan(_%s_backward_plan);\n",myName.c_str()); } fprintf(outfile,"\n"); }; // ****************************************************************************** xmdsVector* xmdsField::createxmdsVector() { if(debugFlag) { printf("xmdsField::createxmdsVector\n"); } xmdsVector* newVector = new xmdsVector(this); myVectorsList.push_back(newVector); return newVector; }; // ****************************************************************************** // ****************************************************************************** // xmdsField protected // ****************************************************************************** // ****************************************************************************** // ****************************************************************************** void xmdsField::writeDefines( FILE *const outfile) const { if(debugFlag) { printf("xmdsField::writeDefines\n"); } fprintf(outfile,"// ********************************************************\n"); fprintf(outfile,"// field %s defines\n",myName.c_str()); fprintf(outfile,"\n"); fprintf(outfile,"#define _%s_ndims %li\n",myName.c_str(),myGeometry.nDims()); for(unsigned long i=0; ilattice); fprintf(outfile,"#define _%s_xmin%li %e\n",myName.c_str(),i,dimI->domain.begin); fprintf(outfile,"#define _%s_dx%li ((%e - %e)/(double)_%s_lattice%li)\n",myName.c_str(),i,dimI->domain.end,dimI->domain.begin,myName.c_str(),i); fprintf(outfile,"#define _%s_dk%li (2*M_PI/(%e - %e))\n",myName.c_str(),i,dimI->domain.end,dimI->domain.begin); fprintf(outfile,"#define d%s _%s_dx%li\n",dimI->name.c_str(),myName.c_str(),i); fprintf(outfile,"#define dk%s _%s_dk%li\n",dimI->name.c_str(),myName.c_str(),i); } fprintf(outfile,"\n"); for(list::const_iterator ppxmdsVector = myVectorsList.begin(); ppxmdsVector != myVectorsList.end(); ppxmdsVector++) { (*ppxmdsVector)->writeDefines(outfile); } fprintf(outfile,"\n"); }; // ****************************************************************************** void xmdsField::writeGlobals( FILE *const outfile) const { if(debugFlag) { printf("xmdsField::writeGlobals\n"); } fprintf(outfile,"// ********************************************************\n"); fprintf(outfile,"// field %s globals\n",myName.c_str()); fprintf(outfile,"\n"); if(myGeometry.nDims()>0) { fprintf(outfile,"const unsigned long _%s_size=_%s_lattice0",myName.c_str(),myName.c_str()); for(unsigned long i=1; iparameters()->stochastic))&(simulation()->parameters()->usempi)) { fprintf(outfile,"fftwnd_mpi_plan _%s_forward_plan;\n",myName.c_str()); fprintf(outfile,"fftwnd_mpi_plan _%s_backward_plan;\n",myName.c_str()); } else { fprintf(outfile,"fftwnd_plan _%s_forward_plan;\n",myName.c_str()); fprintf(outfile,"fftwnd_plan _%s_backward_plan;\n",myName.c_str()); } } fprintf(outfile,"\n"); for(list::const_iterator ppxmdsVector = myVectorsList.begin(); ppxmdsVector != myVectorsList.end(); ppxmdsVector++) { (*ppxmdsVector)->writeGlobals(outfile); } fprintf(outfile,"\n"); }; // ****************************************************************************** void xmdsField::writePrototypes( FILE *const outfile) const { if(debugFlag) { printf("xmdsField::writePrototypes\n"); } fprintf(outfile,"// ********************************************************\n"); fprintf(outfile,"// field %s prototypes\n",myName.c_str()); fprintf(outfile,"\n"); for(list::const_iterator ppxmdsVector = myVectorsList.begin(); ppxmdsVector != myVectorsList.end(); ppxmdsVector++) { (*ppxmdsVector)->writePrototypes(outfile); } fprintf(outfile,"\n"); }; // ****************************************************************************** void xmdsField::writeRoutines( FILE *const outfile) const { if(debugFlag) { printf("xmdsField::writeRoutines\n"); } fprintf(outfile,"// ********************************************************\n"); fprintf(outfile,"// field %s routines\n",myName.c_str()); fprintf(outfile,"// ********************************************************\n"); fprintf(outfile,"\n"); for(list::const_iterator ppxmdsVector = myVectorsList.begin(); ppxmdsVector != myVectorsList.end(); ppxmdsVector++) { (*ppxmdsVector)->writeRoutines(outfile); } fprintf(outfile,"\n"); }; // ****************************************************************************** void xmdsField::setName( const XMLString& yourName) { if(debugFlag) { printf("xmdsField::setName\n"); } myName=yourName; }; // ****************************************************************************** void xmdsField::setGeometry( const xmdsFieldGeometry& yourGeometry) { if(debugFlag) { printf("xmdsField::setGeometry\n"); } myGeometry = yourGeometry; }; // ****************************************************************************** // ****************************************************************************** // xmdsField private // ****************************************************************************** // ****************************************************************************** // ****************************************************************************** xmdsVectorElement* xmdsField::createxmdsVectorElement() { if( debugFlag) { printf("xmdsField::createxmdsVectorElement\n"); } xmdsVectorElement* newVectorElement = new xmdsVectorElement(simulation(),verbose(),this); myVectorsList.push_back(newVectorElement); return newVectorElement; };