/* 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: xmdsintegrate.cc,v 1.23 2005/05/02 02:35:58 sebwuester Exp $ */ /*! @file xmdsintegrate.cc @brief Integrate element parsing classes and methods More detailed explanation... */ #include #include #include #include // ****************************************************************************** // ****************************************************************************** // xmdsIntegrate public // ****************************************************************************** // ****************************************************************************** extern bool debugFlag; long nxmdsIntegrates=0; //!< Number of xmds integrate objects // ****************************************************************************** xmdsIntegrate::xmdsIntegrate( const xmdsSimulation *const yourSimulation, const bool& yourVerboseMode, const bool& adaptiveIP) : xmdsSegment(yourSimulation,yourVerboseMode) { myAdaptiveIP = adaptiveIP; if(debugFlag) { nxmdsIntegrates++; printf("xmdsIntegrate::xmdsIntegrate\n"); printf("nxmdsIntegrates=%li\n",nxmdsIntegrates); } myNextcoKey=0; }; // ****************************************************************************** xmdsIntegrate::~xmdsIntegrate() { if(debugFlag) { nxmdsIntegrates--; printf("xmdsIntegrate::~xmdsIntegrate\n"); printf("nxmdsIntegrates=%li\n",nxmdsIntegrates); } }; // ****************************************************************************** void xmdsIntegrate::processElement( const Element *const yourElement) { if(debugFlag) { printf("xmdsIntegrate::processElement\n"); } list myXMLStringList; list myULongList; if(verbose()) { printf("Processing integrate element ...\n"); } // ************************************ // find 'interval' getAssignmentStrings(yourElement,"interval",1,1,myXMLStringList); myInterval=*myXMLStringList.begin(); if(verbose()) { printf("integrate interval = %s\n",myInterval.c_str()); } // ************************************ // find 'lattice' getAssignmentULongs(yourElement,"lattice",1,1,myULongList); myLattice=*myULongList.begin(); if(myLattice==0) { throw xmdsException(yourElement,"Integration lattice must be >= 1 !"); } if(verbose()) { printf("integrate lattice has %li points\n",myLattice); } // ************************************ // find 'samples' getAssignmentULongs(yourElement,"samples",1,simulation()->output()->nMomentGroups(),mySamplesList); for(long unsigned int i=0;i myBoolList; getAssignmentBools(yourElement,"smallmemory",0,1,myBoolList); if(myBoolList.size()==1) { mySmallmemory=*myBoolList.begin(); if(verbose()) if(mySmallmemory) { printf("\"save memory\" in k_propagate is 'yes'\n"); } else { printf("\"save memory\" in k _propagate 'no'\n"); } } else { printf("\"save memory\" in k_propagate defaulting to no \n"); mySmallmemory=false; } } // ************************************ // find nonoises flag list tempNonoise; myNonoises=false; getAssignmentBools(yourElement,"no_noise",0,1,tempNonoise); if(tempNonoise.size()==1) { if(*tempNonoise.begin()) { myNonoises = true; if(verbose()) printf("No noises will be definied in the filter.\n"); } } if(simulation()->field()->geometry()->nDims()>0) { // ************************************ // find k_operators element const NodeList *const candidateElements = yourElement->getElementsByTagName("k_operators",0); if(candidateElements->length()>1) { throw xmdsException(yourElement,"Multiple elements defined"); } if(candidateElements->length()==1) { // we have a k_operators element const Element *const kPropagationElement = dynamic_cast (candidateElements->item(0)); if(verbose()) { printf("Processing element ...\n"); } // ************************************ // find constantK list aBoolList; getAssignmentBools(kPropagationElement,"constant",0,1,aBoolList); if(aBoolList.size()>0) { myConstantK=*aBoolList.begin(); if(verbose()) { if(myConstantK) { printf("k-operators are propagation independent\n"); } else { printf("k-propagation are propagation dependent\n"); } } } else { myConstantK=1; printf("k-operators defaulting to propagation independent\n"); } if(!myConstantK && myAdaptiveIP){ throw xmdsException("ARK45IP does not work with time-dependent k-operators. Use ARK45EX instead."); } // ************************************ // find vectors getAssignmentStrings(kPropagationElement,"vectors",0,0,myKVectorNamesList); if(myKVectorNamesList.size()==0) { // no vectors specified, therefore assume using only main vector myKVectorNamesList.push_back("main"); } simulation()->field()->processVectors(myKVectorNamesList,simulation()->field()->geometry()->fullSpace()); // ************************************ // find operators getAssignmentStrings(kPropagationElement,"operator_names",1,0,myKOperatorNamesList); // ************************************ // find code myKOperatorsCode=*kPropagationElement->textContent(0); // check for non-white space charaters in code: if(myKOperatorsCode.isAllWhiteSpace()) { throw xmdsException(kPropagationElement,"No code defined!"); } if(verbose()) { printf(" code loaded\n"); } } } // ************************************ // find vectors getAssignmentStrings(yourElement,"vectors",1,0,myVectorNamesList); // Vectors are now required by law in order to place the code element /* if(myVectorNamesList.size()==0) { // no vectors specified, therefore assume using only main vector myVectorNamesList.push_back("main"); }*/ simulation()->field()->processVectors(myVectorNamesList,0); // ************************************ // find code myPropagationCode=*yourElement->textContent(0); // check for non-white space charaters in code: if(myPropagationCode.isAllWhiteSpace()) { throw xmdsException(yourElement,"No propagation code defined!"); } if(verbose()) { printf("processing propagation code ...\n"); } if(simulation()->field()->geometry()->nDims()>0) { // ************************************ // find cross_propagation const NodeList *const candidateElements = yourElement->getElementsByTagName("cross_propagation",0); if(candidateElements->length() > 1) { throw xmdsException(yourElement,"only one allowed"); } if(candidateElements->length() == 1) { // we have a cross_propagation element const Element *const crossPropagationElement = dynamic_cast (candidateElements->item(0)); // ...but not if we're distributing the vector over many processors! if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { throw xmdsException(crossPropagationElement,"I really can't handle using MPI when there are cross-propagation elements."); } // ************************************ // find cross propagating vectors getAssignmentStrings(crossPropagationElement,"vectors",1,0,myCrossVectorNamesList); for(list::const_iterator pXMLString = myCrossVectorNamesList.begin(); pXMLString != myCrossVectorNamesList.end(); pXMLString++) { if(*pXMLString=="main") { throw xmdsException(crossPropagationElement,"Cannot cross-propagate 'main' vector!"); } } simulation()->field()->processVectors(myCrossVectorNamesList,0); // ************************************ // find 'prop_dim' list anXMLStringList; getAssignmentStrings(crossPropagationElement,"prop_dim",1,1,anXMLStringList); // now find which member of the main field dimensions it is if(!simulation()->field()->geometry()->getDimNumber(*anXMLStringList.begin(),myCrossDimNumber)) { sprintf(errorMessage(),"prop_dim '%s' not a dimension of main field",anXMLStringList.begin()->c_str()); throw xmdsException(crossPropagationElement,errorMessage()); } if(verbose()) { printf("cross prop_dim is field dimension number %li\n",myCrossDimNumber); } // ************************************ // find cross_propagation code myCrossPropagationCode=*crossPropagationElement->textContent(0); // check for non-white space charaters in code: if(myCrossPropagationCode.isAllWhiteSpace()) { throw xmdsException(crossPropagationElement,"No code defined!"); } if(verbose()) { printf("cross_propagation code loaded\n"); } } } // ************************************ // process elements in order to process and place the code elements myNumNonLoopPropagation=0; myNumIntegrateMomentGroups=0; long unsigned int i; const NodeList* myElements; const Element* nextElement; myElements = yourElement->getElementsByTagName("*",0); i=0; while(ilength()) { nextElement = dynamic_cast (myElements->item(i)); if(*nextElement->nodeName() == "functions") { XMLString someLoopPropagationCode = *nextElement->textContent(0); // check for non-white space charaters in code: if(someLoopPropagationCode.isAllWhiteSpace()) { throw xmdsException(nextElement,"No code defined!"); } if(verbose()) { printf(" code loaded\n"); } myNumNonLoopPropagation++; myNonLoopPropagationCodeList.push_back(someLoopPropagationCode); myCodeElementList.push_back(*nextElement->nodeName()); } else if(*nextElement->nodeName() == "moment_group") { integrateMomentGroup tempIntegrateMG; XMLString someCode = *nextElement->textContent(0); // check for non-white space charaters in code: if(someCode.isAllWhiteSpace()) { throw xmdsException(nextElement,"No code defined!"); } if(verbose()) { printf(" code loaded\n"); } tempIntegrateMG.integrateMomentGroupCode = someCode; getAssignmentStrings(nextElement,"moments",1,0,tempIntegrateMG.momentNameList); getAssignmentBools(nextElement,"integrate_dimension",1,simulation()->field()->geometry()->nDims(),tempIntegrateMG.integrateDimensionList); myNumIntegrateMomentGroups++; myIntegrateMomentGroupList.push_back(tempIntegrateMG); myCodeElementList.push_back(*nextElement->nodeName()); } else if(*nextElement->nodeName() == "vectors") { myCodeElementList.push_back(*nextElement->nodeName()); } i++; } }; // ****************************************************************************** // ****************************************************************************** // xmdsIntegrate protected // ****************************************************************************** // ****************************************************************************** // ****************************************************************************** const bool xmdsIntegrate::Smallmemory() const { if(debugFlag) { printf("xmdsIntegrate::Smallmemory\n"); } return mySmallmemory; }; // ****************************************************************************** void xmdsIntegrate::writeDefines( FILE *const outfile) const { if(debugFlag) { printf("xmdsIntegrate::writeDefines\n"); } if(usesKOperators()) { if((myAdaptiveIP && !Smallmemory()) || (!myAdaptiveIP && constantK())) { fprintf(outfile,"// integrate defines\n"); fprintf(outfile,"\n"); fprintf(outfile,"#define _segment%li_nkoperators %li\n",segmentNumber,(long)myKOperatorNamesList.size()); fprintf(outfile,"\n"); } } }; // ****************************************************************************** void xmdsIntegrate::writeGlobals( FILE *const outfile) const { if(debugFlag) { printf("xmdsIntegrate::writeGlobals\n"); } if(usesKOperators()) { if(myAdaptiveIP){ if(usesKOperators()) if(!Smallmemory()) { fprintf(outfile,"// integrate globals\n"); fprintf(outfile,"\n"); for(int n=1;n<6;n++) if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { fprintf(outfile,"complex *_segment%li_k_operator_field_%i;\n",segmentNumber,n); } else { fprintf(outfile,"complex *_segment%li_k_operator_field_%i = new complex[_%s_size*_segment%li_nkoperators];\n", segmentNumber,n,simulation()->field()->name()->c_str(),segmentNumber); } fprintf(outfile,"\n"); } }else{ if(constantK()) { fprintf(outfile,"// integrate globals\n"); fprintf(outfile,"\n"); if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { fprintf(outfile,"complex *_segment%li_k_operator_field;\n",segmentNumber); } else { fprintf(outfile,"complex *_segment%li_k_operator_field = new complex[_%s_size*_segment%li_nkoperators];\n", segmentNumber,simulation()->field()->name()->c_str(),segmentNumber); } fprintf(outfile,"\n"); } } } }; // ****************************************************************************** void xmdsIntegrate::writePrototypes( FILE *const outfile) const { if(debugFlag) { printf("xmdsIntegrate::writePrototypes\n"); } writexSpacePrototype(outfile); }; // ****************************************************************************** void xmdsIntegrate::writeRoutines( FILE *const outfile) const { if(debugFlag) { printf("xmdsIntegrate::writeRoutines\n"); } writexSpaceRoutine(outfile); }; // ****************************************************************************** const XMLString* xmdsIntegrate::interval() const { if(debugFlag) { printf("xmdsIntegrate::interval\n"); } return &myInterval; }; // ****************************************************************************** unsigned long xmdsIntegrate::lattice() const { if(debugFlag) { printf("xmdsIntegrate::lattice\n"); } return myLattice; }; // ****************************************************************************** unsigned long xmdsIntegrate::samples( const unsigned long& index) const { if(debugFlag) { printf("xmdsIntegrate::KVectorNamesList\n"); } if(index>=mySamplesList.size()) { throw xmdsException("Internal range error in xmdsIntegrate::samples"); } list::const_iterator pULong = mySamplesList.begin(); for(unsigned long i=0; i* xmdsIntegrate::KVectorNamesList() const { if(debugFlag) { printf("xmdsIntegrate::KVectorNamesList\n"); } return &myKVectorNamesList; }; // ****************************************************************************** bool xmdsIntegrate::constantK() const { if(debugFlag) { printf("xmdsIntegrate::constantK\n"); } return myConstantK; }; // ****************************************************************************** bool xmdsIntegrate::noNoises() const { if(debugFlag) { printf("xmdsIntegrate::noNoises\n"); } return myNonoises; }; // ****************************************************************************** unsigned long xmdsIntegrate::nKOperators() const { if(debugFlag) { printf("xmdsIntegrate::nKOperators\n"); } return myKOperatorNamesList.size(); }; // ****************************************************************************** const XMLString* xmdsIntegrate::KOperator( const unsigned long& index) const { if(debugFlag) { printf("xmdsIntegrate::KOperator\n"); } if(index>=myKOperatorNamesList.size()) { throw xmdsException("Internal range error in xmdsIntegrate::KOperator"); } list::const_iterator pXMLString = myKOperatorNamesList.begin(); for(unsigned long i=0; i::const_iterator pXMLString = myKOperatorNamesList.begin(); pXMLString != myKOperatorNamesList.end(); pXMLString++) { if(*pXMLString==operatorName) { return 1; } index++; } return 0; }; // ****************************************************************************** const XMLString* xmdsIntegrate::KOperatorsCode() const { if(debugFlag) { printf("xmdsIntegrate::KOperatorsCode\n"); } return &myKOperatorsCode; }; // ****************************************************************************** list* xmdsIntegrate::vectorNamesList() { if(debugFlag) { printf("xmdsIntegrate::vectorNamesList\n"); } return &myVectorNamesList; }; // ****************************************************************************** const list* xmdsIntegrate::vectorNamesList() const { if(debugFlag) { printf("xmdsIntegrate::vectorNamesList\n"); } return &myVectorNamesList; }; // ****************************************************************************** XMLString* xmdsIntegrate::propagationCode() { if(debugFlag) { printf("xmdsIntegrate::propagationCode\n"); } return &myPropagationCode; }; // ****************************************************************************** const XMLString* xmdsIntegrate::propagationCode() const { if(debugFlag) { printf("xmdsIntegrate::propagationCode\n"); } return &myPropagationCode; }; // ****************************************************************************** const list* xmdsIntegrate::crossVectorNamesList() const { if(debugFlag) { printf("xmdsIntegrate::crossVectorNamesList\n"); } return &myCrossVectorNamesList; }; // ****************************************************************************** unsigned long xmdsIntegrate::crossDimNumber() const { if(debugFlag) { printf("xmdsIntegrate::crossDimNumber\n"); } return myCrossDimNumber; }; // ****************************************************************************** const XMLString* xmdsIntegrate::crossPropagationCode() const { if(debugFlag) { printf("xmdsIntegrate::crossPropagationCode\n"); } return &myCrossPropagationCode; }; // ****************************************************************************** list* xmdsIntegrate::nonLoopPropagationCodeList() { if(debugFlag) { printf("xmdsIntegrate::nonLoopPropagationCodeList\n"); } return &myNonLoopPropagationCodeList; }; // ****************************************************************************** const list* xmdsIntegrate::nonLoopPropagationCodeList() const { if(debugFlag) { printf("xmdsIntegrate::nonLoopPropagationCodeList\n"); } return &myNonLoopPropagationCodeList; }; // ****************************************************************************** list* xmdsIntegrate::codeElementList() { if(debugFlag) { printf("xmdsIntegrate::codeElementList\n"); } return &myCodeElementList; }; // ****************************************************************************** const list* xmdsIntegrate::codeElementList() const { if(debugFlag) { printf("xmdsIntegrate::codeElementList\n"); } return &myCodeElementList; }; // ****************************************************************************** bool xmdsIntegrate::usesKOperators() const { if(debugFlag) { printf("xmdsIntegrate::usesKOperators\n"); } return (mycoStructList.size()>0); }; // ****************************************************************************** const bool xmdsIntegrate::AdaptiveIP() const { if(debugFlag) { printf("xmdsIntegrate::AdaptiveIP\n"); } return myAdaptiveIP; }; // ****************************************************************************** long unsigned int xmdsIntegrate::numNonLoopPropagation() const { if(debugFlag) { printf("xmdsIntegrate::numNonLoopPropagation\n"); } return (myNumNonLoopPropagation); }; // ****************************************************************************** long unsigned int xmdsIntegrate::numIntegrateMomentGroups() const { if(debugFlag) { printf("xmdsIntegrate::numIntegrateMomentGroups\n"); } return (myNumIntegrateMomentGroups); }; // ****************************************************************************** list* xmdsIntegrate::integrateMomentGroupList() { if(debugFlag) { printf("xmdsIntegrate::integrateMomentGroupList\n"); } return &myIntegrateMomentGroupList; }; // ****************************************************************************** const list* xmdsIntegrate::integrateMomentGroupList() const { if(debugFlag) { printf("xmdsIntegrate::integrateMomentGroupList\n"); } return &myIntegrateMomentGroupList; }; // ****************************************************************************** bool xmdsIntegrate::getcoStruct( const unsigned long& componentNumber, const coStruct*& thecoStruct) const { if(debugFlag) { printf("xmdsIntegrate::getcoStruct\n"); } for(list::const_iterator pcoStruct = mycoStructList.begin(); pcoStruct != mycoStructList.end(); pcoStruct++) { if(pcoStruct->componentNumber == componentNumber) { thecoStruct = &*pcoStruct; return 1; } } return 0; }; // ****************************************************************************** bool xmdsIntegrate::getcoKey( const unsigned long& componentNumber, const unsigned long& operatorNumber, unsigned long& coKey) const { if(debugFlag) { printf("xmdsIntegrate::getcoPairKey\n"); } const coStruct* thecoStruct; if(!getcoStruct(componentNumber,thecoStruct)) { return 0; } list::const_iterator pULong1 = thecoStruct->operatorNumbersList.begin(); list::const_iterator pULong2 = thecoStruct->coKeysList.begin(); while(pULong1 != thecoStruct->operatorNumbersList.end()) { if(*pULong1==operatorNumber) { coKey = *pULong2; return 1; } pULong1++; pULong2++; } return 0; }; // ****************************************************************************** unsigned long xmdsIntegrate::addcoPair( const unsigned long& componentNumber, const unsigned long& operatorNumber) { if(debugFlag) { printf("xmdsIntegrate::addcoPair\n"); } coStruct* existingcoStruct = 0; for(list::iterator pcoStruct = mycoStructList.begin(); pcoStruct != mycoStructList.end(); pcoStruct++) { if(pcoStruct->componentNumber == componentNumber) { existingcoStruct = &*pcoStruct; } } if(existingcoStruct != 0) { existingcoStruct->operatorNumbersList.push_back(operatorNumber); existingcoStruct->coKeysList.push_back(myNextcoKey); } else { coStruct nextcoStruct; nextcoStruct.componentNumber = componentNumber; nextcoStruct.operatorNumbersList.push_back(operatorNumber); nextcoStruct.coKeysList.push_back(myNextcoKey); mycoStructList.push_back(nextcoStruct); } myNextcoKey++; return myNextcoKey-1; }; // ****************************************************************************** bool xmdsIntegrate::findNextcoPair( XMLString& operatorName, XMLString& componentName, unsigned long& start, unsigned long& end) const { if(debugFlag) { printf("xmdsIntegrate::findNextcoPair\n"); } // here we are looking for the next **** operatorName S? '[' S? componentName S? ']' **** production // starting from the offset provided const char* code=myPropagationCode.c_str(); end = start; unsigned long openBrace; unsigned long nameStart; unsigned long nameEnd; // find next [ while((code[end] != '[') && (code[end] != 0)) { end++; } if(code[end] == 0) { return 0; } // ok, we found the first [ openBrace = end; // now skip white space end++; while(XMLChar::isWhiteSpace(code[end]) && (code[end] != 0)) { end++; } if(code[end] == 0) { return 0; } if(!(XMLChar::isLatinLetter(code[end]) | (code[end]=='_'))) { return 0; } nameStart = end; end++; while((XMLChar::isLatinLetter(code[end]) | XMLChar::isLatinDigit(code[end]) | (code[end]=='_'))&(code[end] != 0)) { end++; } if(code[end] == 0) { return 0; } nameEnd = end; //check that we have a ] on the end // skip white space while(XMLChar::isWhiteSpace(code[end]) && (code[end] != 0)) { end++; } if(code[end] != ']') { return 0; } // ok, we definititely had a nice clean [name] end++; myPropagationCode.subString(componentName,nameStart,nameEnd); // now work backwards to find the operator name start=openBrace-1; // skip any white space while(XMLChar::isWhiteSpace(code[start])&(start>0)) { start--; } if(!(XMLChar::isLatinLetter(code[start]) | XMLChar::isLatinDigit(code[start]) | (code[start]=='_'))) { return 0; } nameEnd=start+1; while((XMLChar::isLatinLetter(code[start]) | XMLChar::isLatinDigit(code[start]) | (code[start]=='_'))&(start>0)) { start--; } if(!(XMLChar::isLatinLetter(code[start]) | XMLChar::isLatinDigit(code[start]) | (code[start]=='_'))) { start++; } if(!(XMLChar::isLatinLetter(code[start]) | (code[start]=='_'))) { return 0; } nameStart=start; myPropagationCode.subString(operatorName,nameStart,nameEnd); return 1; }; // ****************************************************************************** void xmdsIntegrate::writexSpacePrototype( FILE *const outfile) const { if(debugFlag) { printf("xmdsIntegrate::writexSpacePrototype\n"); } fprintf(outfile,"void _segment%li_calculate_delta_a(\n",segmentNumber); fprintf(outfile," const double& _step"); fprintf(outfile,",\n const unsigned long cycle"); if((simulation()->parameters()->stochastic)&&(!myNonoises)) { fprintf(outfile,",\n const double *const _noise_vector"); } fprintf(outfile,");\n"); fprintf(outfile,"\n"); }; // ****************************************************************************** void xmdsIntegrate::writexSpaceRoutine( FILE *const outfile) const { if(debugFlag) { printf("xmdsIntegrate::writexSpaceRoutine\n"); } const unsigned long nDims = simulation()->field()->geometry()->nDims(); const char *const fieldName = simulation()->field()->name()->c_str(); fprintf(outfile,"// *************************\n"); fprintf(outfile,"void _segment%li_calculate_delta_a(\n",segmentNumber); fprintf(outfile," const double& _step"); fprintf(outfile,",\n const unsigned long cycle"); if((simulation()->parameters()->stochastic)&&(!myNonoises)) { fprintf(outfile,",\n const double *const _noise_vector"); } fprintf(outfile,") {\n"); fprintf(outfile,"\n"); const xmdsVector* mainVector; if(!simulation()->field()->getVector("main",mainVector)) { throw xmdsException("Internal error in xmdsIntegrate::writexSpaceRoutine: cannot find 'main' vector"); } const char* typeName=""; if(mainVector->vectorType()==COMPLEX) { typeName="complex"; } else if(mainVector->vectorType()==DOUBLE) { typeName="double"; } for(unsigned long i=0;inComponents();i++) { fprintf(outfile,"%s d%s_d%s;\n",typeName,mainVector->componentName(i)->c_str(),simulation()->parameters()->propDimName.c_str()); } fprintf(outfile,"\n"); // add cross vectors to total vectors to use, but no duplicating names! list myTotalVectorsList = *vectorNamesList(); for(list::const_iterator pXMLString = crossVectorNamesList()->begin(); pXMLString != crossVectorNamesList()->end(); pXMLString++) { list::const_iterator pXMLString2 = myTotalVectorsList.begin(); while((pXMLString2 != myTotalVectorsList.end()) && (*pXMLString2 != *pXMLString)) { pXMLString2++; } if(*pXMLString2 != *pXMLString) { myTotalVectorsList.push_back(*pXMLString); } } simulation()->field()->vectors2space(outfile,0,myTotalVectorsList,""); if(crossVectorNamesList()->size() > 0) { fprintf(outfile,"_segment%li_calculate_cross_field();\n",segmentNumber); fprintf(outfile,"\n"); } if((simulation()->parameters()->stochastic)&&(!myNonoises)) { fprintf(outfile,"const double* _noises = _noise_vector;\n"); fprintf(outfile,"\n"); } list::const_iterator nextNLPElement = myNonLoopPropagationCodeList.begin(); list::const_iterator nextMGElement = myIntegrateMomentGroupList.begin(); list theCodeList = *codeElementList(); if(!(theCodeList.size()==1+numIntegrateMomentGroups()+numNonLoopPropagation())) { throw xmdsException("The list of integrate code elements is the wrong length!"); } long unsigned int whichMG = 0; list deleteMGArrayList; for(list::const_iterator codeElement = theCodeList.begin(); codeElement != theCodeList.end(); codeElement++) { if(!strcmp(codeElement->c_str(),"vectors")) { simulation()->field()->openLoops(outfile,0,myTotalVectorsList); fprintf(outfile,"\n"); char indent[64]; for(unsigned long i=0;i::const_iterator tempNextMGElement = myIntegrateMomentGroupList.begin(); tempNextMGElement != myIntegrateMomentGroupList.end(); tempNextMGElement++) { long unsigned int nDimsRemaining = simulation()->field()->geometry()->nDims(); tempWhichMG++; for(list::const_iterator nextIntegrateDimension = tempNextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != tempNextMGElement->integrateDimensionList.end(); nextIntegrateDimension++){ if(*nextIntegrateDimension) { nDimsRemaining--; } } if(nDimsRemaining>0) { fprintf(outfile," long _img%li_pointer = ",tempWhichMG); for(long unsigned int j=0; j::const_iterator nextIntegrateDimension = tempNextMGElement->integrateDimensionList.begin(); while(*nextIntegrateDimension) { nextIntegrateDimension++; whichMoment++; } fprintf(outfile,"_i%li",whichMoment); nextIntegrateDimension++; whichMoment++; for(long unsigned int k=0; kmomentNameList.size()); } } fprintf(outfile,"// ************** propagation code **************\n"); fprintf(outfile,"%s\n",propagationCode()->c_str()); fprintf(outfile,"// **********************************************\n"); fprintf(outfile,"\n"); for(long unsigned int i=0;inComponents();i++) { fprintf(outfile,"%s_active_%s_main[_%s_main_index_pointer + %li] = d%s_d%s*_step;\n", indent,fieldName,fieldName,i,mainVector->componentName(i)->c_str(),simulation()->parameters()->propDimName.c_str()); } fprintf(outfile,"\n"); if((simulation()->parameters()->stochastic)&&(!myNonoises)) { fprintf(outfile,"%s_noises += _n_noises;\n",indent); fprintf(outfile,"\n"); } simulation()->field()->closeLoops(outfile,0,myTotalVectorsList); fprintf(outfile,"\n"); } else if(!strcmp(codeElement->c_str(),"functions")) { fprintf(outfile,"// ************** propagation code **************\n"); fprintf(outfile,"%s\n",nextNLPElement->c_str()); fprintf(outfile,"// **********************************************\n"); fprintf(outfile,"\n"); nextNLPElement++; } else if(!strcmp(codeElement->c_str(),"moment_group")) { whichMG++; long unsigned int nDimsRemaining = simulation()->field()->geometry()->nDims(); for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++){ if(*nextIntegrateDimension) { nDimsRemaining--; } } if(nDimsRemaining>0) { deleteMGArrayList.push_back(whichMG); } fprintf(outfile,"// ************** integrate moment group code **************\n"); //setup defines for the integrate_moment_groups if they are arrays long unsigned int whichMoment=0; if(nDimsRemaining>0) { for(list::const_iterator nextMomentName = nextMGElement->momentNameList.begin(); nextMomentName != nextMGElement->momentNameList.end(); nextMomentName++){ fprintf(outfile,"#define %s _img%li_array[_img%li_pointer+%li]\n",nextMomentName->c_str(),whichMG,whichMG,whichMoment); whichMoment++; } } fprintf(outfile,"\n"); //setup actual arrays for the integrate_moment_groups (MPI and non-MPI) if(nDimsRemaining>0) { fprintf(outfile,"complex *_img%li_array = new complex[%i",whichMG,nextMGElement->momentNameList.size()); if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { whichMoment=0; for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++) { if(!*nextIntegrateDimension) { if(whichMoment==0){ fprintf(outfile,"*local_nx"); } else { fprintf(outfile,"*_%s_lattice%li",fieldName,whichMoment); } } whichMoment++; } } else { whichMoment=0; for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++) { if(!*nextIntegrateDimension) { fprintf(outfile,"*_%s_lattice%li",fieldName,whichMoment); } whichMoment++; } } fprintf(outfile,"];\n"); } else { for(list::const_iterator nextMomentName = nextMGElement->momentNameList.begin(); nextMomentName != nextMGElement->momentNameList.end(); nextMomentName++) { fprintf(outfile,"complex %s = rcomplex(0,0);\n",nextMomentName->c_str()); } } fprintf(outfile,"\n"); //zero the arrays and setup a local environment for the sum if(nDimsRemaining>0) { fprintf(outfile,"for(long _i0=0; _i0<%i",nextMGElement->momentNameList.size()); if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { whichMoment=0; for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++) { if(!*nextIntegrateDimension) { if(whichMoment==0){ fprintf(outfile,"*local_nx"); } else { fprintf(outfile,"*_%s_lattice%li",fieldName,whichMoment); } } whichMoment++; } } else { whichMoment=0; for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++) { if(!*nextIntegrateDimension) { fprintf(outfile,"*_%s_lattice%li",fieldName,whichMoment); } whichMoment++; } } fprintf(outfile,"; _i0++) {\n"); fprintf(outfile," _img%li_array[_i0] = rcomplex(0,0);\n",whichMG); fprintf(outfile,"}\n"); } fprintf(outfile,"{\n"); // open loops simulation()->field()->openLoops(outfile,0,myTotalVectorsList); // pointer definition if(nDimsRemaining>0) { fprintf(outfile," long _img%li_pointer = ",whichMG); for(long unsigned int j=0; j::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); while(*nextIntegrateDimension) { nextIntegrateDimension++; whichMoment++; } fprintf(outfile,"_i%li",whichMoment); nextIntegrateDimension++; whichMoment++; for(long unsigned int k=0; kmomentNameList.size()); } // code fprintf(outfile,"%s\n",nextMGElement->integrateMomentGroupCode.c_str()); // close loops simulation()->field()->closeLoops(outfile,0,myTotalVectorsList); fprintf(outfile,"}\n"); // if there was any integration, multiply by the relevant volume element if(nDimsRemainingfield()->geometry()->nDims()) { if(nDimsRemaining>0) { fprintf(outfile,"for(long _i0=0; _i0<%i",nextMGElement->momentNameList.size()); if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { whichMoment=0; for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++) { if(!*nextIntegrateDimension) { if(whichMoment==0){ fprintf(outfile,"*local_nx"); } else { fprintf(outfile,"*_%s_lattice%li",fieldName,whichMoment); } } whichMoment++; } } else { whichMoment=0; for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++) { if(!*nextIntegrateDimension) { fprintf(outfile,"*_%s_lattice%li",fieldName,whichMoment); } whichMoment++; } } whichMoment=0; fprintf(outfile,"; _i0++) {\n"); fprintf(outfile," _img%li_array[_i0] = _img%li_array[_i0]",whichMG,whichMG); for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++){ if(*nextIntegrateDimension) { fprintf(outfile,"*_%s_dx%li",fieldName,whichMoment); } whichMoment++; } fprintf(outfile,";\n"); fprintf(outfile," }\n"); } else { for(list::const_iterator nextMomentName = nextMGElement->momentNameList.begin(); nextMomentName != nextMGElement->momentNameList.end(); nextMomentName++) { whichMoment = 0; fprintf(outfile," %s = %s",nextMomentName->c_str(),nextMomentName->c_str()); for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++){ if(*nextIntegrateDimension) { fprintf(outfile,"*_%s_dx%li",fieldName,whichMoment); } whichMoment++; } fprintf(outfile,";\n"); } } } // if mpi and first variable integrated then mpireduce if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { if(* nextMGElement->integrateDimensionList.begin()) { if(nDimsRemaining>0) { fprintf(outfile,"\n complex *_temp_img%li_array = new complex[%i",whichMG,nextMGElement->momentNameList.size()); whichMoment=0; for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++) { if(!*nextIntegrateDimension) { fprintf(outfile,"*_%s_lattice%li",fieldName,whichMoment); } whichMoment++; } fprintf(outfile,"];\n"); fprintf(outfile," MPI_Reduce(_img%li_array,_temp_img%li_array,2*%i",whichMG,whichMG,nextMGElement->momentNameList.size()); whichMoment=0; for(list::const_iterator nextIntegrateDimension = nextMGElement->integrateDimensionList.begin(); nextIntegrateDimension != nextMGElement->integrateDimensionList.end(); nextIntegrateDimension++) { if(!*nextIntegrateDimension) { fprintf(outfile,"*_%s_lattice%li",fieldName,whichMoment); } whichMoment++; } fprintf(outfile,",MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);\n"); fprintf(outfile,"\n delete[] _temp_img%li_array;\n",whichMG); } else { fprintf(outfile,"\n complex *_temp%li_mpireduce = new complex;\n",whichMG); for(list::const_iterator nextMomentName = nextMGElement->momentNameList.begin(); nextMomentName != nextMGElement->momentNameList.end(); nextMomentName++) { fprintf(outfile," MPI_Reduce(&%s,_temp%li_mpireduce,2,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);\n",nextMomentName->c_str(),whichMG); fprintf(outfile,"\n delete _temp%li_mpireduce;\n",whichMG); } } } } fprintf(outfile,"\n"); fprintf(outfile,"// *********************************************************\n"); fprintf(outfile,"\n"); nextMGElement++; } else { throw xmdsException("Unknown code element in the integrate block!"); } } // delete any arrays that were generated for(list::const_iterator deleteMGArray = deleteMGArrayList.begin(); deleteMGArray != deleteMGArrayList.end(); deleteMGArray++) { fprintf(outfile,"delete[] _img%li_array;\n",*deleteMGArray); } fprintf(outfile,"}\n"); fprintf(outfile,"\n"); }; // ****************************************************************************** // ****************************************************************************** // xmdsIntegrate private // ****************************************************************************** // ****************************************************************************** // ****************************************************************************** void xmdsIntegrate::outputSampleCount() const { if(debugFlag) { printf("xmdsIntegrate::outputSampleCount\n"); } simulation()->output()->addSamples(mySamplesList); }; // ****************************************************************************** void xmdsIntegrate::writeInitialisationCalls( FILE *const outfile) const { if(debugFlag) { printf("xmdsIntegrate::writeInitialisationCalls\n"); } if(usesKOperators()&&!Smallmemory()) { if(myAdaptiveIP){ for(int i=1;i<6;i++) if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) { fprintf(outfile,"_segment%li_k_operator_field_%i = new complex[total_local_size*_segment%li_nkoperators];\n", segmentNumber,i,segmentNumber); fprintf(outfile,"\n"); } }else{ if(constantK()) fprintf(outfile,"_segment%li_calculate_k_operator_field();\n",segmentNumber); } } };