23 #ifdef PROTEUS_USE_SIMMETRIX
30 #include <SimMeshTools.h>
32 pAManager SModel_attManager(pModel model);
52 #ifdef PROTEUS_USE_SIMMETRIX
53 Sim_readLicenseFile(0);
60 global[0] = global[1] = global[2] = global[3] = 0;
61 local[0] = local[1] = local[2] = local[3] = 0;
81 target_element_count = 0;
115 #ifdef PROTEUS_USE_SIMMETRIX
117 Sim_unregisterAllKeys();
122 static bool ends_with(std::string
const& str, std::string
const& ext)
124 return str.size() >= ext.size() &&
125 str.compare(str.size() - ext.size(), ext.size(), ext) == 0;
138 comm_size = PCU_Comm_Peers();
139 comm_rank = PCU_Comm_Self();
140 if (ends_with(meshFile,
".msh")){
141 m = apf::loadMdsFromGmsh(gmi_load(modelFile), meshFile);
142 std::cout<<
"Boundary Condition functionality has not been built in for gmsh yet.\n";
144 else if (ends_with(modelFile,
".smd")){
145 m = apf::loadMdsMesh(modelFile, meshFile);
146 modelFileName=(
char *) malloc(
sizeof(
char) * strlen(modelFile));
151 m = apf::loadMdsMesh(modelFile, meshFile);
161 comm_size = PCU_Comm_Peers();
162 comm_rank = PCU_Comm_Self();
163 m = apf::loadMdsMesh(
".null", meshFile);
191 #ifdef PROTEUS_USE_SIMMETRIX
195 pAManager attmngr = SModel_attManager(model);
196 pACase acase = AMAN_findCaseByType(attmngr,
"problem definition");
198 if(comm_rank==0)std::cout<<
"Found case, setting the model"<<std::endl;
199 AttCase_setModel(acase,model);
201 AttCase_associate(acase,NULL);
204 GFIter gfIter = GM_faceIter(model);
205 pAttribute Att[GM_numFaces(model)];
206 int attMap[GM_numFaces(model)];
209 char strAtt[2][25] = {
"traction vector",
"comp3"};
212 while(gFace = GFIter_next(gfIter))
214 if(GEN_attrib((pGEntity)gFace,strAtt[0]))
216 modelEntTag=GEN_tag((pGEntity)gFace);
217 Att[nF]=GEN_attrib((pGEntity)gFace,strAtt[0]);
218 attMap[nF] = modelEntTag;
222 GFIter_delete(gfIter);
224 apf::MeshIterator* fIter = m->begin(FACE);
225 apf::MeshEntity* fEnt;
229 const int bcFlag[
nsd+1] = {0,1,1,1};
232 char label[9],labelflux[4][9],type_flag;
234 sprintf(label,
"BCtype");
235 BCtag = m->createIntTag(label,4);
236 for(
int idx=0;idx<4;idx++)
238 if(idx == 0) sprintf(&type_flag,
"p");
239 else if(idx == 1) sprintf(&type_flag,
"u");
240 else if(idx == 2) sprintf(&type_flag,
"v");
241 else if(idx == 3) sprintf(&type_flag,
"w");
242 if(idx>0) sprintf(labelflux[idx],
"%c_flux",type_flag);
245 while(fEnt = m->iterate(fIter))
247 apf::ModelEntity* me=m->toModel(fEnt);
248 modelEntTag = m->getModelTag(me);
249 apf::ModelEntity* boundary_face = m->findModelEntity(FACE,modelEntTag);
252 apf::MeshElement* testElem = apf::createMeshElement(m,fEnt);
254 for(
int idx=1;idx<
nsd+1;idx++)
255 fluxtag[idx]= m->createDoubleTag(labelflux[idx],numqpt);
256 apf::destroyMeshElement(testElem);
258 if(me==boundary_face)
260 for(
int i=0;i<nF;i++)
262 if(attMap[i]==modelEntTag)
264 apf::MeshElement* testElem = apf::createMeshElement(m,fEnt);
265 double data[
nsd+1][numqpt];
266 for(
int k=0; k<numqpt;k++)
269 apf::Vector3 evalPtGlobal;
270 apf::mapLocalToGlobal(testElem,evalPt,evalPtGlobal);
271 double evalPtSim[
nsd];
272 evalPtGlobal.toArray(evalPtSim);
273 for(
int j=0;j<
nsd;j++)
274 data[j+1][k]=AttributeTensor1_evalDS((pAttributeTensor1)Att[i], j,evalPtSim);
276 m->setIntTag(fEnt,
BCtag,&(bcFlag[0]));
277 for(
int idx=1;idx<
nsd+1;idx++)
279 m->setDoubleTag(fEnt,
fluxtag[idx],data[idx]);
281 apf::destroyMeshElement(testElem);
286 int dummy[4] = {0,0,0,0};
287 m->setIntTag(fEnt,
BCtag,&(dummy[0]));
292 int dummy[4] = {0,0,0,0};
293 m->setIntTag(fEnt,
BCtag,&(dummy[0]));
298 AMAN_release( attmngr );
301 std::cout<<
"Case not found, no BCs?\n"<<std::endl;
305 if(comm_rank==0)std::cout<<
"Finished reading and storing diffusive flux BCs\n";
309 static int countTotal(apf::Mesh* m,
int dim)
311 int total = apf::countOwned(m, dim);
312 PCU_Add_Ints(&total, 1);
331 apf::Field* currentField;
346 currentField = samSz::isoSize(m);
350 apf::Field* errorField = sizeFieldList.front();
354 apf::Field *errorTriggered = apf::createLagrangeField(m,
"errorTriggered", apf::SCALAR, 1);
356 apf::MeshEntity* ent;
357 apf::MeshIterator* it = m->begin(0);
358 while( (ent = m->iterate(it)) )
360 double h_current = apf::getScalar(currentField,ent,0);
361 double h_needed = apf::getScalar(errorField,ent,0);
362 if(h_current>h_needed*1.5){
364 apf::setScalar(errorTriggered,ent,0,h_current/h_needed*1.0);
371 apf::setScalar(errorTriggered,ent,0,-1);
378 while( (ent = m->iterate(it)) )
380 double h_current = apf::getScalar(currentField,ent,0);
381 double h_needed = apf::getScalar(errorField,ent,0);
382 apf::setScalar(errorField,ent,0,h_current/h_needed*1.0);
386 assertFlag = adaptFlag;
387 PCU_Add_Ints(&assertFlag,1);
392 double totalNodes = countTotal(m,0);
393 double triggeredPercentage = assertFlag*100.0/totalNodes;
395 sprintf(buffer,
"Need to error adapt %f%%",triggeredPercentage);
409 apf::destroyField(currentField);
411 apf::destroyField(errorTriggered);
426 apf::Field* errorTriggered;
427 if(m->findField(
"errorTriggered"))
428 errorTriggered = m->findField(
"errorTriggered");
430 errorTriggered = apf::createField(m,
"errorTriggered",apf::SCALAR,apf::getVoronoiShape(m->getDimension(),1));
432 apf::Field* error_current = m->findField(
"VMSH1");
433 apf::Field* error_reference=NULL;
436 if(m->findField(
"errorRate"))
437 apf::destroyField(m->findField(
"errorRate"));
438 apf::Field* errorRateField = apf::createField(m,
"errorRate",apf::SCALAR,apf::getVoronoiShape(m->getDimension(),1));
441 apf::MeshEntity* ent;
442 apf::MeshIterator* it;
446 it = m->begin(m->getDimension());
447 while( (ent = m->iterate(it) ) )
449 apf::setScalar(errorTriggered,ent,0,-1.0);
450 apf::setScalar(errorRateField,ent,0,0.0);
453 logEvent(
"SET ERROR TRIGGERED!",4);
460 if(!m->findField(
"error_reference"))
462 T_reference = T_current;
463 error_reference = apf::createField(m,
"error_reference",apf::SCALAR,apf::getVoronoiShape(
nsd,1));
464 apf::copyData(error_reference,error_current);
465 logEvent(
"SUCCESSFULLY COPIED!",4);
471 error_reference = m->findField(
"error_reference");
476 if(m->findField(
"sizeRatio"))
477 apf::destroyField(m->findField(
"sizeRatio"));
478 apf::Field* sizeRatioField = apf::createField(m,
"sizeRatio",apf::SCALAR,apf::getVoronoiShape(m->getDimension(),1));
480 it = m->begin(m->getDimension());
482 while( (ent = m->iterate(it) ) )
484 double err_local_current = apf::getScalar(error_current,ent,0);
485 double err_local_ref = apf::getScalar(error_reference,ent,0);
486 double errorRate = (err_local_current-err_local_ref)/(T_current-T_reference);
487 apf::setScalar(errorRateField,ent,0,errorRate);
488 double err_predict = errorRate*delta_T_next + err_local_current;
496 apf::MeshElement* element = apf::createMeshElement(m, ent);
498 if (m->getDimension() == 2)
499 h_old = apf::computeLargestHeightInTri(m,ent);
501 h_old = apf::computeShortestHeightInTet(m,ent);
502 h_new = h_old * pow((target_error / err_predict),2.0/(2.0*(1.0)+
nsd));
508 double sizeRatio_local_predict = h_old/h_new;
509 apf::setScalar(sizeRatioField,ent,0,sizeRatio_local_predict);
510 apf::destroyMeshElement(element);
515 if(apf::getScalar(errorTriggered,ent,0)==1)
518 apf::setScalar(errorTriggered,ent,0,2.0);
521 apf::setScalar(errorTriggered,ent,0,1.0);
524 apf::setScalar(errorTriggered,ent,0,-1.0);
531 logEvent(
"Adapting because upper limit was reached.",4);
535 assertFlag = adaptFlag;
536 PCU_Add_Ints(&assertFlag,1);
543 logEvent(
"Need to error based adapt!!!",4);
565 it = m->begin(m->getDimension());
566 while( (ent = m->iterate(it) ) )
568 double err_local_current = apf::getScalar(error_current,ent,0);
570 apf::setScalar(error_reference,ent,0,err_local_current);
575 T_reference = T_current;
590 logEvent(
"will adapt because of interface",4);
595 logEvent(
"will adapt because of error",4);
622 apf::Field* currentField;
635 currentField = samSz::isoSize(m);
636 double edgeRatio = 1.5;
641 apf::Field* interfaceField = sizeFieldList.front();
646 apf::MeshEntity* ent;
647 apf::MeshIterator* it = m->begin(0);
648 while( (ent = m->iterate(it)) )
650 double h_current = apf::getScalar(currentField,ent,0);
651 double h_needed = apf::getScalar(interfaceField,ent,0);
652 if(h_current/h_needed > edgeRatio){
658 assertFlag = adaptFlag;
659 PCU_Add_Ints(&assertFlag,1);
662 apf::destroyField(currentField);
663 apf::destroyField(interfaceField);
689 double t1 = PCU_Time();
691 double t2 = PCU_Time();
693 std::ofstream myfile;
694 myfile.open(
"error_estimator_timing.txt", std::ios::app );
695 myfile << t2-t1<<std::endl;
699 if((
hasVMS) && std::string(inputString)==
""){
711 if(
nAdapt>1 && std::string(inputString)==
"interface")
713 else if(
nAdapt > 2 && std::string(inputString)==
"")
717 size_iso = m->findField(
"proteus_size");
719 size_frame = m->findField(
"proteus_sizeFrame");
720 size_scale = m->findField(
"proteus_sizeScale");
734 isotropicIntersect();
738 sprintf(namebuffer,
"pumi_preadapt_%i",
nAdapt);
739 apf::writeVtkFiles(namebuffer, m);
747 freeField(errRho_reg);
748 freeField(errRel_reg);
752 if(PCU_Comm_Self()==0) std::cout<<
"cleared VMS field\n";
761 for (
int d = 0; d <= m->getDimension(); ++d)
762 freeNumbering(local[d]);
764 apf::Field* adaptSize;
765 apf::Field* adaptFrame;
770 in = ma::makeAdvanced(ma::configureUniformRefine(m));
771 in->shouldFixShape=
false;
774 assert(size_iso || (size_scale && size_frame));
777 adaptSize = apf::createFieldOn(m,
"adapt_size", apf::VECTOR);
778 adaptFrame = apf::createFieldOn(m,
"adapt_frame", apf::MATRIX);
779 apf::copyData(adaptSize, size_scale);
780 apf::copyData(adaptFrame, size_frame);
781 in = ma::makeAdvanced(ma::configure(m, adaptSize, adaptFrame));
784 adaptSize = apf::createFieldOn(m,
"adapt_size", apf::SCALAR);
785 apf::copyData(adaptSize, size_iso);
786 in = ma::makeAdvanced(ma::configure(m, adaptSize));
790 ma::validateInput(in);
791 in->shouldRunPreZoltan =
true;
792 in->shouldRunMidZoltan =
true;
793 in->shouldRunPostZoltan =
true;
794 in->maximumImbalance = 1.05;
795 in->maximumIterations =
numIter;
798 in->shouldSnap =
true;
799 in->shouldTransferParametric=
true;
802 in->shouldSnap =
false;
806 double t1 = PCU_Time();
808 ma::adaptVerbose(in);
809 double t2 = PCU_Time();
837 sprintf(namebuffer,
"pumi_postadapt_%i",
nAdapt);
838 apf::writeVtkFiles(namebuffer, m);
843 apf::destroyField(adaptSize);
845 apf::destroyField(adaptFrame);
849 m->writeNative(
"DEBUG_restart.smb");
863 ma::SizeField* isf =
new ma::IdentitySizeField(m);
864 apf::MeshIterator* it = m->begin(m->getDimension());
867 while ((e = m->iterate(it)))
868 minq =
std::min(minq, ma::measureElementQuality(m, isf, e));
871 return PCU_Min_Double(minq);
881 apf::Field* voff = m->findField(
"vof");
884 apf::MeshIterator* it = m->begin(m->getDimension());
886 while ((e = m->iterate(it))) {
887 apf::MeshElement* elem = apf::createMeshElement(m,e);
888 apf::Element* voff_elem = apf::createElement(voff, elem);
890 for(
int l = 0; l < apf::countIntPoints(elem,
int_order); ++l) {
893 double vof_val = apf::getScalar(voff_elem,qpt);
894 double rho_val =
getMPvalue(vof_val,rho[0],rho[1]);
895 double weight = apf::getIntWeight(elem,
int_order,l);
897 apf::getJacobian(elem,qpt,J);
898 double Jdet = apf::getJacobianDeterminant(J,m->getDimension());
899 mass += rho_val*weight*Jdet;
901 apf::destroyElement(voff_elem);
902 apf::destroyMeshElement(elem);
905 PCU_Add_Doubles(&mass,1);
914 m->writeNative(meshFile);
924 for(
int i =0;i<m->countFields();i++)
926 apf::Field* sample = m->getField(i);
931 apf::Field* sample = m->findField(
"velocity_old");
934 sample = m->findField(
"vof_old");
936 sample = m->findField(
"ls_old");
938 sample = m->findField(
"phi");
940 sample = m->findField(
"phi_old");
942 sample = m->findField(
"phi_old_old");
944 sample = m->findField(
"phid_old");
946 sample = m->findField(
"phiCorr");
948 sample = m->findField(
"phiCorr_old");
950 sample = m->findField(
"phiCorr_old_old");
952 sample = m->findField(
"p_old");
954 sample = m->findField(
"p");
956 sample = m->findField(
"p_old_old");
959 sample = m->findField(
"VMSH1");
961 sample = m->findField(
"VMSL2");
965 apf::DynamicArray<apf::MeshTag*> listTags;
966 m->getTags(listTags);
967 int nTags = listTags.getSize();
968 int numDim = m->getDimension();
969 for(
int i=0; i < nTags; i++)
971 std::string ignoreString (
"proteus_number");
972 std::string tagName (m->getTagName(listTags[i]));
973 if(tagName.find(ignoreString) != std::string::npos)
978 for(
int j=0;j<(numDim+1);j++)
980 apf::MeshIterator* it = m->begin(j);
981 apf::MeshEntity* ent;
982 while( (ent = m->iterate(it)) )
984 if(m->hasTag(ent,listTags[i]))
985 m->removeTag(ent,listTags[i]);
989 m->destroyTag(listTags[i]);
1000 int MeshAdaptPUMIDrvr::setAdaptProperties(std::vector<std::string> sizeInputs,
bool in_adapt,
double in_hmax,
double in_hmin,
double in_hphi,
int in_numAdaptSteps,
double in_targetError,
double in_gradingFactor,
bool in_logging,
int in_numIterations)
1002 for (std::vector<std::string>::iterator it = sizeInputs.begin() ; it != sizeInputs.end(); ++it)
1006 if(*it ==
"interface")
1008 if(*it ==
"error_vms")
1010 if(*it ==
"error_erm")
1019 if(PCU_Comm_Self()==0)
1020 printf(
"MeshAdapt: Setting hmax=%lf, hmin=%lf, numIters(meshadapt)=%d\n",
1023 target_error = in_targetError;