/*
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: xmdsintegrateex.cc,v 1.14 2004/07/13 05:29:38 paultcochrane Exp $
*/
/*! @file xmdsintegrateex.cc
@brief Integrate element parsing classes and methods; explicit picture
More detailed explanation...
*/
#include<xmlbasics.h>
#include<dom3.h>
#include<xmdsutils.h>
#include<xmdsclasses.h>
// ******************************************************************************
// ******************************************************************************
// xmdsIntegrateEX public
// ******************************************************************************
// ******************************************************************************
extern bool debugFlag;
long nxmdsIntegrateEXs=0; //!< Number of xmds integrate EX objects
// ******************************************************************************
xmdsIntegrateEX::xmdsIntegrateEX(
const xmdsSimulation *const yourSimulation,
const bool& yourVerboseMode) :
xmdsIntegrate(yourSimulation,yourVerboseMode) {
if(debugFlag) {
nxmdsIntegrateEXs++;
printf("xmdsIntegrateEX::xmdsIntegrateEX\n");
printf("nxmdsIntegrateEXs=%li\n",nxmdsIntegrateEXs);
}
};
// ******************************************************************************
xmdsIntegrateEX::~xmdsIntegrateEX() {
if(debugFlag) {
nxmdsIntegrateEXs--;
printf("xmdsIntegrateEX::~xmdsIntegrateEX\n");
printf("nxmdsIntegrateEXs=%li\n",nxmdsIntegrateEXs);
}
};
// ******************************************************************************
void xmdsIntegrateEX::processElement(
const Element *const yourElement) {
if(debugFlag) {
printf("xmdsIntegrateEX::processElement\n");
}
// ************************************
// parse code for operators
const xmdsVector* mainVector;
if(!simulation()->field()->getVector("main",mainVector)) {
throw xmdsException("Internal error in xmdsIntegrateEX::processElement: cannot find 'main' vector");
}
XMLString* theCode = propagationCode();
XMLString nextOperatorName;
XMLString nextComponentName;
unsigned long start=0;
unsigned long end=0;
char s[256];
list<XMLString> coVectorComponentNamesList;
// first need to get all co pairs
while(end<theCode->length()) {
if(findNextcoPair(nextOperatorName,nextComponentName,start,end)) {
unsigned long nextComponentNumber;
if(!mainVector->getComponent(nextComponentName,nextComponentNumber)) {
sprintf(errorMessage(),"[%s] is not a component of the main vector",nextComponentName.c_str());
throw xmdsException(yourElement,errorMessage());
}
unsigned long nextOperatorNumber;
if(!getKOperator(nextOperatorName,nextOperatorNumber)) {
sprintf(errorMessage(),"'%s' was not defined in <k_operators>",nextOperatorName.c_str());
throw xmdsException(yourElement,errorMessage());
}
sprintf(s,"_segment%li_co_term_%s_%s",segmentNumber,nextOperatorName.c_str(),nextComponentName.c_str());
const XMLString nextVectorComponentName = s;
unsigned long coKey;
if(!getcoKey(nextComponentNumber,nextOperatorNumber,coKey)) {
if(verbose()) {
printf("adding operator-component pair: %s[%s]\n",nextOperatorName.c_str(),nextComponentName.c_str());
}
coKey = addcoPair(nextComponentNumber,nextOperatorNumber);
coVectorComponentNamesList.push_back(nextVectorComponentName);
}
theCode->replaceData(start,end-start,nextVectorComponentName);
start = start+nextVectorComponentName.length();
}
else {
start = end;
}
}
if(coVectorComponentNamesList.size()>0) {
xmdsVector* coVector = simulation()->field()->createxmdsVector();
sprintf(s,"segment%li_co_terms",segmentNumber);
coVector->setName(s);
coVector->setVectorType(COMPLEX);
coVector->setComponents(coVectorComponentNamesList);
list<XMLString> tempVectorNamesList;
tempVectorNamesList.push_back("main");
tempVectorNamesList.push_back(s);
simulation()->field()->processVectors(tempVectorNamesList,simulation()->field()->geometry()->fullSpace());
vectorNamesList()->push_back(s);
}
};
// ******************************************************************************
// ******************************************************************************
// xmdsIntegrateEX protected
// ******************************************************************************
// ******************************************************************************
// ******************************************************************************
void xmdsIntegrateEX::writePrototypes(
FILE *const outfile) const {
if(debugFlag) {
printf("xmdsIntegrateEX::writePrototypes\n");
}
if(usesKOperators()) {
fprintf(outfile,"// integrate (EX) prototypes\n");
fprintf(outfile,"\n");
if(constantK()) {
fprintf(outfile,"void _segment%li_calculate_k_operator_field();\n",segmentNumber);
fprintf(outfile,"\n");
}
fprintf(outfile,"void _segment%li_calculate_co_terms();\n",segmentNumber);
}
};
// ******************************************************************************
void xmdsIntegrateEX::writeRoutines(
FILE *const outfile) const {
if(debugFlag) {
printf("xmdsIntegrateEX::writeRoutines\n");
}
if(usesKOperators()) {
if(constantK()) {
writeCalculatekOperatorFieldRoutine(outfile);
writeCalculateCOTermsConstantKRoutine(outfile);
}
else
writeCalculateCOTermsTimeDepKRoutine(outfile);
}
};
// ******************************************************************************
// ******************************************************************************
// xmdsIntegrateEX private
// ******************************************************************************
// ******************************************************************************
// ******************************************************************************
void xmdsIntegrateEX::writeCalculatekOperatorFieldRoutine(
FILE *const outfile) const {
if(debugFlag) {
printf("xmdsIntegrateEX::writeCalculatekOperatorFieldRoutine\n");
}
const unsigned long nDims = simulation()->field()->geometry()->nDims();
const unsigned long fullSpace = simulation()->field()->geometry()->fullSpace();
unsigned long i;
fprintf(outfile,"// *************************\n");
fprintf(outfile,"void _segment%li_calculate_k_operator_field() {\n",segmentNumber);
fprintf(outfile,"\n");
for(i=0;i<nKOperators();i++) {
fprintf(outfile,"complex %s;\n",KOperator(i)->c_str());
}
fprintf(outfile,"\n");
if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) {
fprintf(outfile,"_segment%li_k_operator_field = new complex[total_local_size*_segment%li_nkoperators];\n",
segmentNumber,segmentNumber);
fprintf(outfile,"\n");
}
simulation()->field()->vectors2space(outfile,fullSpace,*KVectorNamesList(),"");
fprintf(outfile,"unsigned long _k_operator_index_pointer=0;\n");
simulation()->field()->openLoops(outfile,fullSpace,*KVectorNamesList());
char indent[64];
for(i=0;i<nDims;i++) {
indent[i]=0x09;
}
indent[nDims]=0;
fprintf(outfile,"\n");
fprintf(outfile,"// ********** Code from k_operators *************\n");
fprintf(outfile,"%s\n",KOperatorsCode()->c_str());
fprintf(outfile,"// **********************************************\n");
fprintf(outfile,"\n");
for(i=0;i<nKOperators();i++) {
fprintf(outfile,"%s_segment%li_k_operator_field[_k_operator_index_pointer + %li] = %s;\n",
indent,segmentNumber,i,KOperator(i)->c_str());
}
fprintf(outfile,"\n");
fprintf(outfile,"%s_k_operator_index_pointer += _segment%li_nkoperators;\n",indent,segmentNumber);
simulation()->field()->closeLoops(outfile,fullSpace,*KVectorNamesList());
fprintf(outfile,"}\n");
fprintf(outfile,"\n");
};
// ******************************************************************************
void xmdsIntegrateEX::writeCalculateCOTermsConstantKRoutine(
FILE *const outfile) const {
if(debugFlag) {
printf("xmdsIntegrateEX::writeCalculateCOTermsConstantKRoutine\n");
}
const unsigned long fullSpace = simulation()->field()->geometry()->fullSpace();
const char *const fieldName = simulation()->field()->name()->c_str();
char coVectorName[256];
sprintf(coVectorName,"segment%li_co_terms",segmentNumber);
const xmdsVector* mainVector;
if(!simulation()->field()->getVector("main",mainVector)) {
throw xmdsException("Internal error in xmdsIntegrateEX::writeCalculateCOTermsConstantKRoutine: cannot find 'main' vector");
}
fprintf(outfile,"// *************************\n");
fprintf(outfile,"void _segment%li_calculate_co_terms() {\n",segmentNumber);
fprintf(outfile,"\n");
fprintf(outfile,"double _temp;\n");
fprintf(outfile,"unsigned long _segment%li_kop_index_pointer=0;\n",segmentNumber);
fprintf(outfile,"unsigned long _active_%s_index_pointer=0;\n",fieldName);
fprintf(outfile,"unsigned long _%s_segment_%li_co_terms_index_pointer=0;\n",fieldName,segmentNumber);
fprintf(outfile,"\n");
list<XMLString> tempVectorNamesList;
tempVectorNamesList.push_back("main");
simulation()->field()->vectors2space(outfile,fullSpace,tempVectorNamesList,"");
if(simulation()->parameters()->usempi&!simulation()->parameters()->stochastic) {
fprintf(outfile,"for(long _i0=0;_i0<total_local_size;_i0++) {\n");
}
else {
fprintf(outfile,"for(unsigned long _i0=0;_i0<_%s_size;_i0++) {\n",fieldName);
}
fprintf(outfile,"\n");
for(unsigned long i=0; i<mainVector->nComponents(); i++) {
const coStruct* thecoStruct;
if(getcoStruct(i,thecoStruct)) {
list<unsigned long>::const_iterator pULong1 = thecoStruct->operatorNumbersList.begin();
list<unsigned long>::const_iterator pULong2 = thecoStruct->coKeysList.begin();
while(pULong1 != thecoStruct->operatorNumbersList.end()) {
fprintf(outfile,"\n");
fprintf(outfile," _temp = _segment%li_k_operator_field[_segment%li_kop_index_pointer + %li].re\n",
segmentNumber,segmentNumber,*pULong1);
fprintf(outfile," *_active_%s_main[_active_%s_index_pointer + %li].re\n",fieldName,fieldName,i);
fprintf(outfile," - _segment%li_k_operator_field[_segment%li_kop_index_pointer + %li].im\n",
segmentNumber,segmentNumber,*pULong1);
fprintf(outfile," *_active_%s_main[_active_%s_index_pointer + %li].im;\n",fieldName,fieldName,i);
fprintf(outfile,"\n");
fprintf(outfile," _%s_segment%li_co_terms[_%s_segment_%li_co_terms_index_pointer + %li].im =\n",
fieldName,segmentNumber,fieldName,segmentNumber,*pULong2);
fprintf(outfile," _segment%li_k_operator_field[_segment%li_kop_index_pointer + %li].re\n",
segmentNumber,segmentNumber,*pULong1);
fprintf(outfile," *_active_%s_main[_active_%s_index_pointer + %li].im\n",fieldName,fieldName,i);
fprintf(outfile," + _segment%li_k_operator_field[_segment%li_kop_index_pointer + %li].im\n",
segmentNumber,segmentNumber,*pULong1);
fprintf(outfile," *_active_%s_main[_active_%s_index_pointer + %li].re;\n",fieldName,fieldName,i);
fprintf(outfile,"\n");
fprintf(outfile," _%s_segment%li_co_terms[_%s_segment_%li_co_terms_index_pointer + %li].re=_temp;\n",
fieldName,segmentNumber,fieldName,segmentNumber,*pULong2);
pULong1++;
pULong2++;
}
}
}
fprintf(outfile," _segment%li_kop_index_pointer+=_segment%li_nkoperators;\n",segmentNumber,segmentNumber);
fprintf(outfile," _active_%s_index_pointer+=_%s_main_ncomponents;\n",fieldName,fieldName);
fprintf(outfile," _%s_segment_%li_co_terms_index_pointer+=_%s_segment%li_co_terms_ncomponents;\n",fieldName,segmentNumber,fieldName,segmentNumber);
fprintf(outfile," }\n");
fprintf(outfile,"\n");
fprintf(outfile,"_%s_segment%li_co_terms_space=%li;\n",fieldName,segmentNumber,fullSpace);
fprintf(outfile,"}\n");
fprintf(outfile,"\n");
};
// ******************************************************************************
void xmdsIntegrateEX::writeCalculateCOTermsTimeDepKRoutine(
FILE *const outfile) const {
if(debugFlag) {
printf("xmdsIntegrateIP::writeCalculateCOTermsTimeDepKRoutine\n");
}
const unsigned long nDims = simulation()->field()->geometry()->nDims();
const unsigned long fullSpace = simulation()->field()->geometry()->fullSpace();
const char *const fieldName = simulation()->field()->name()->c_str();
const xmdsVector* mainVector;
if(!simulation()->field()->getVector("main",mainVector)) {
throw xmdsException("Internal error in xmdsIntegrateIP::writeCalculateCOTermsTimeDepKRoutine: cannot find 'main' vector");
}
fprintf(outfile,"// *************************\n");
fprintf(outfile,"void _segment%li_calculate_co_terms() {\n",segmentNumber);
fprintf(outfile,"\n");
for(unsigned long i=0;i<nKOperators();i++) {
fprintf(outfile,"complex %s;\n",KOperator(i)->c_str());
}
fprintf(outfile,"\n");
fprintf(outfile,"double _temp;\n");
fprintf(outfile,"\n");
simulation()->field()->vectors2space(outfile,fullSpace,*KVectorNamesList(),"");
list<XMLString> tempVectorNamesList = *KVectorNamesList();
char coVectorName[256];
sprintf(coVectorName,"segment%li_co_terms",segmentNumber);
tempVectorNamesList.push_back(coVectorName);
simulation()->field()->openLoops(outfile,fullSpace,tempVectorNamesList);
char indent[64];
for(unsigned long i=0;i<nDims;i++) {
indent[i]=0x09;
}
indent[nDims]=0;
fprintf(outfile,"\n");
fprintf(outfile,"// ********** Code from k_operators *************\n");
fprintf(outfile,"%s\n",KOperatorsCode()->c_str());
fprintf(outfile,"// **********************************************\n");
fprintf(outfile,"\n");
for(unsigned long i=0; i<mainVector->nComponents(); i++) {
const coStruct* thecoStruct;
if(getcoStruct(i,thecoStruct)) {
for (list<unsigned long>::const_iterator pULong = thecoStruct->operatorNumbersList.begin(); pULong != thecoStruct->operatorNumbersList.end(); pULong++) {
fprintf(outfile,"%s_temp = %s.re*%s.re - %s.im*%s.im;\n",
indent,KOperator(*pULong)->c_str(),mainVector->componentName(i)->c_str(),
KOperator(*pULong)->c_str(),mainVector->componentName(i)->c_str());
fprintf(outfile,"%s_segment%li_co_term_%s_%s.im = %s.re*%s.im + %s.im*%s.re;\n",
indent,segmentNumber,KOperator(*pULong)->c_str(),mainVector->componentName(i)->c_str(),
KOperator(*pULong)->c_str(),mainVector->componentName(i)->c_str(),
KOperator(*pULong)->c_str(),mainVector->componentName(i)->c_str());
fprintf(outfile,"%s_segment%li_co_term_%s_%s.re=_temp;\n",
indent,segmentNumber,KOperator(*pULong)->c_str(),mainVector->componentName(i)->c_str());
fprintf(outfile,"\n");
}
}
}
simulation()->field()->closeLoops(outfile,fullSpace,tempVectorNamesList);
fprintf(outfile,"\n");
fprintf(outfile,"_%s_segment%li_co_terms_space=%li;\n",fieldName,segmentNumber,fullSpace);
fprintf(outfile,"}\n");
fprintf(outfile,"\n");
};
syntax highlighted by Code2HTML, v. 0.9.1